基于动态代理的远程服务:
- 服务类:
- 实现接口
- 具体方法
- 工厂类:
- 发布服务
- 代理服务
- 服务端:
- 指定端口,发布服务
- 客户端
- 建立通信,获取代理,传输数据,获取结果
基于动态代理和网络传输的远程服务,包含以下部分:
服务类:实现具体的功能操作;
工厂端:提供两个功能,一是为服务器端提供实时监听服务,通过指定端口建立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")); } }