基于动态代理的远程服务

来源:互联网 发布:披甲龙龟事件知乎 编辑:程序博客网 时间:2024/05/18 02:20
基于动态代理的远程服务:
  1. 服务类:
    • 实现接口
    • 具体方法
  2. 工厂类:
    • 发布服务
    • 代理服务
  3. 服务端:
    • 指定端口,发布服务
  4. 客户端
    • 建立通信,获取代理,传输数据,获取结果
过程原理:

基于动态代理和网络传输的远程服务,包含以下部分:
服务类:实现具体的功能操作;
工厂端:提供两个功能,一是为服务器端提供实时监听服务,通过指定端口建立Socket通信,获取从客户端传来的参数和方法名,然后执行服务器端指定的对象的方法,获取结果后通过Socket传输回客户端;二是为客户端提供动态代理,为客户端创建代理对象,并将客户端的方法绑定到动态代理上,当客户端执行对应方法时,实际上并没有真正执行,而是执行的绑定的动态代理中的操作,即将客户端中的方法名、参数通过Socket通信传递到服务器,等待服务器接收参数并执行后回传返回值,将返回值作为执行结果返回给客户端,从而实现了远程代理服务。
服务器:创建服务类对象,通过工厂类的方法将创建监听等客户端连接
客户端:创建服务类实例,指向工厂类的动态代理,服务类实例通过动态代理来执行方法,并通过动态代理来获取返回值。
说明:关于动态代理的原理,需要通过JVM的类加载机制和反射机制来深入分析,将会在另作说明。


实现过程:
  • 服务类:
    • 定义接口
public interface Hello {        public String hello(String world);                public String others(String o);}
    • 重写方法
public class HelloImpl implements Hello{        @Override        public String hello(String world){                return "hello "+world;        }        @Override        public String others(String o) {                return "success..."+o;        }}

  • 工厂类:
    • 发布服务
public static void publish(Object service,int port) throws IOException{                //打开服务                ServerSocket server = new ServerSocket(port);                //建立多个通道                while(true){                        Socket socket =server.accept();                        new Thread(new Runnable(){                                public void run() {                                        try {                                                ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());                                                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());                                                //获取方法名                                                String method =input.readUTF();                                                //获取方法参数                                                Class<?>[] params =(Class<?>[])input.readObject();                                                //获取方法实参                                                Object[] arguments = (Object[])input.readObject();                                                   //调用方法  返还                                                Method m =service.getClass().getMethod(method, params);                                                Object result=m.invoke(service, arguments);                                                output.writeObject(result);                                                output.flush();                                        } catch (Exception e) {                                                e.printStackTrace();                                        }finally {                        try {                        //关闭                                                        socket.close();                                                } catch (IOException e) {                                                }                    }                                                                        }                                                                                        }).start();                }        }

代理服务:
  • 服务端:
    • 指定端口,发布服务
public class RpcPublish {        public static void main(String[] args) throws IOException {                Hello hello=new HelloImpl();                RPCFactory.publish(hello , 1234);        }}

  • 客户端
    • 监听接口,获取实例,实现功能
public class RpcSubscribe {        public static void main(String[] args) {                Hello hello=RPCFactory.subscribe("localhost", 1234, Hello.class);                System.out.println(hello.hello("aaaa"));                System.out.println(hello.others("aaaa"));        }}


原创粉丝点击