Java远程方法调用中动态代理类的使用

客户端 和 服务端公用文件
share
    |__call
    |       |__Call.java
    |__service
             |__HelloService.java
客户端代码
locale
    |__client
             |__SimpleClient.java
             |__ProxyFactory.java
             |__TcpConnector.java
服务端代码
remote
     |__server
     |        |__SimpleServer.java
     |__service
              |__HelloServiceImpl.java
程序实现目标
    客户端通过动态代理类调用服务端HelloServiceImpl.java 中的方法

 

Java代码 复制代码
  1. // share.call.Call.java   
  2. package share.call;   
  3.   
  4. import java.io.Serializable;   
  5.   
  6. /**  
  7.  *@date 2010-3-13 下午04:32:04  
  8.  *@author dycc  
  9.  *@file share.call.Call.java  
  10.  */  
  11. public class Call implements Serializable{   
  12.     /**  
  13.      *   
  14.      */  
  15.     private static final long serialVersionUID = 1L;   
  16.     private String className;   
  17.     private String methodName;   
  18.     @SuppressWarnings(value="unchecked")   
  19.     private Class[] paramTypes;   
  20.     private Object[] params;   
  21.     private Object result;   
  22.        
  23.     public Call(){   
  24.     }   
  25.     @SuppressWarnings(value="unchecked")   
  26.     public Call(String className,String methodName,   
  27.             Class[] paramTypes,Object[] params){   
  28.         this.className = className;   
  29.         this.methodName = methodName;   
  30.         this.paramTypes = paramTypes;   
  31.         this.params = params;   
  32.     }   
  33.     public String getClassName() {   
  34.         return className;   
  35.     }   
  36.     public void setClassName(String className) {   
  37.         this.className = className;   
  38.     }   
  39.     public String getMethodName() {   
  40.         return methodName;   
  41.     }   
  42.     public void setMethodName(String methodName) {   
  43.         this.methodName = methodName;   
  44.     }   
  45.     @SuppressWarnings(value="unchecked")   
  46.     public Class[] getParamTypes() {   
  47.         return paramTypes;   
  48.     }   
  49.     @SuppressWarnings(value="unchecked")   
  50.     public void setParamTypes(Class[] paramTypes) {   
  51.         this.paramTypes = paramTypes;   
  52.     }   
  53.     public Object[] getParams() {   
  54.         return params;   
  55.     }   
  56.     public void setParams(Object[] params) {   
  57.         this.params = params;   
  58.     }   
  59.     public Object getResult() {   
  60.         return result;   
  61.     }   
  62.     public void setResult(Object result) {   
  63.         this.result = result;   
  64.     }   
  65.     public String toString(){   
  66.         StringBuffer sb = new StringBuffer();   
  67.         sb.append("{className=" + className);   
  68.         sb.append(",methodName=" + methodName);   
  69.         sb.append(",result=" + result);   
  70.         sb.append("}");   
  71.         return sb.toString();   
  72.     }   
  73. }   
  74.   
  75. // share.service.HelloService.java   
  76. package share.service;   
  77.   
  78. import java.util.Date;   
  79.   
  80. /**  
  81.  *@date 2010-3-13 下午04:29:29  
  82.  *@author dycc  
  83.  *@file share.service.HelloService.java  
  84.  */  
  85. public interface HelloService {   
  86.     public String echo(String msg);   
  87.     public Date getTime();   
  88. }   
  89.   
  90. // locale.client.SimpleClient.java   
  91. package locale.client;   
  92.   
  93. import share.service.HelloService;   
  94.   
  95. /**  
  96.  *@date 2010-3-13 下午04:58:48  
  97.  *@author dycc  
  98.  *@file locale.client.SimpleClient.java  
  99.  */  
  100. public class SimpleClient {   
  101.     /**  
  102.      * 通过代理类调用远程方法  
  103.      */  
  104.     public void invoke(){   
  105.         HelloService hello = (HelloService)ProxyFactory.getProxy(   
  106.                 HelloService.class,"remote.service.HelloServiceImpl",   
  107.                 "localhost"8002);   
  108.         String result = hello.echo("music");   
  109.         System.out.println("result=" + result);   
  110.     }   
  111.        
  112.     public static void main(String[] args){   
  113.         SimpleClient client = new SimpleClient();   
  114.         client.invoke();   
  115.     }   
  116. }   
  117.   
  118. // locale.client.ProxyFactory.java   
  119. package locale.client;   
  120.   
  121. import java.lang.reflect.InvocationHandler;   
  122. import java.lang.reflect.Method;   
  123. import java.lang.reflect.Proxy;   
  124. import java.rmi.RemoteException;   
  125.   
  126. import share.call.Call;   
  127.   
  128. /**  
  129.  *@date 2010-3-13 下午08:21:01  
  130.  *@author dycc  
  131.  *@file locale.client.ProxyFactory.java  
  132.  */  
  133. public class ProxyFactory {   
  134.     /**  
  135.      * 获取动态代理类  
  136.      * @param classType 接口  
  137.      * @param className 实现类名称   
  138.      * @param ip        ip 地址  
  139.      * @param port      端口  
  140.      * @return  
  141.      */  
  142.     @SuppressWarnings(value="unchecked")   
  143.     public static Object getProxy(Class classType,   
  144.             final String className,   
  145.             final String ip,final int port){   
  146.         // start   
  147.         InvocationHandler handler = new InvocationHandler(){   
  148.             public Object invoke(Object proxy, Method method, Object[] args)   
  149.                     throws Throwable {   
  150.                 System.out.println("--- before " + method.getName() + "---");   
  151.                 TcpConnector connector = new TcpConnector(ip, port);   
  152.                 Call call = new Call(className,method.getName(),   
  153.                         method.getParameterTypes(),args);   
  154.                 call = (Call)connector.invoke(call);   
  155.                 Object result = call.getResult();   
  156.                 if(result instanceof Throwable){   
  157.                     return new RemoteException(method.getName() + "invoke failed",   
  158.                             (Throwable)result);   
  159.                 }   
  160.                 System.out.println("--- after " + method.getName() + "---");   
  161.                 connector.close();   
  162.                 return result;   
  163.             }   
  164.         };   
  165.         return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),   
  166.                 new Class[]{classType}, handler);   
  167.     }   
  168. }   
  169.   
  170. // locale.client.TcpConnector.java   
  171. package locale.client;   
  172.   
  173. import java.io.IOException;   
  174. import java.io.ObjectInputStream;   
  175. import java.io.ObjectOutputStream;   
  176. import java.net.Socket;   
  177.   
  178. /**  
  179.  *@date 2010-3-13 下午08:25:04  
  180.  *@author dycc  
  181.  *@file locale.client.TcpConnector.java  
  182.  */  
  183. public class TcpConnector {   
  184.     private Socket socket;   
  185.     private ObjectInputStream in;   
  186.     private ObjectOutputStream out;   
  187.     /**  
  188.      * 构造器  
  189.      * @param ip  
  190.      * @param port  
  191.      * @throws IOException  
  192.      */  
  193.     public TcpConnector(String ip,int port)throws IOException{   
  194.         socket = new Socket(ip,port);   
  195.     }   
  196.     /**  
  197.      * 调用远程方法  
  198.      * @param obj  
  199.      * @throws IOException  
  200.      */  
  201.     public Object invoke(Object obj)throws IOException,ClassNotFoundException{   
  202.         if(out == null){   
  203.             out = new ObjectOutputStream(socket.getOutputStream());   
  204.         }   
  205.         out.writeObject(obj);   
  206.         out.flush();   
  207.         if(in == null){   
  208.             in = new ObjectInputStream(socket.getInputStream());   
  209.         }   
  210.         return in.readObject();   
  211.     }   
  212.     /**  
  213.      * 关闭连接  
  214.      */  
  215.     public void close(){   
  216.         try{   
  217.             if(in != null){   
  218.                 in.close();   
  219.             }   
  220.             if(out != null){   
  221.                 out.close();   
  222.             }   
  223.             if(socket != null){   
  224.                 socket.close();   
  225.             }   
  226.         } catch(Exception e){   
  227.         }   
  228.     }   
  229. }   
  230.   
  231. // remote.server.SimpleServer.java   
  232. package remote.server;   
  233.   
  234. import java.io.IOException;   
  235. import java.io.ObjectInputStream;   
  236. import java.io.ObjectOutputStream;   
  237. import java.lang.reflect.Method;   
  238. import java.net.ServerSocket;   
  239. import java.net.Socket;   
  240. import java.util.HashMap;   
  241. import java.util.Map;   
  242.   
  243. import share.call.Call;   
  244.   
  245.   
  246. /**  
  247.  *@date 2010-3-13 下午04:38:44  
  248.  *@author dycc  
  249.  *@file remote.server.SimpleServer.java  
  250.  */  
  251. public class SimpleServer {   
  252.     private Map<String,Object> map_objs = new HashMap<String,Object>();   
  253.     private ObjectInputStream in;   
  254.     private ObjectOutputStream out;   
  255.     /**  
  256.      * 服务端在 8002 端口监听客户端请求  
  257.      * @throws IOException  
  258.      */  
  259.     public void service()throws IOException{   
  260.         ServerSocket server_socket = new ServerSocket(8002);   
  261.         System.out.println("----- server started. -----");   
  262.         while(true){   
  263.             try{   
  264.                 Socket socket = server_socket.accept();   
  265.                 // ObjectInputStream 会发生阻塞!!   
  266.                 in = new ObjectInputStream(socket.getInputStream());   
  267.                 Call call = (Call)in.readObject();   
  268.                 System.out.println("-- get call [" + call.getClassName()   
  269.                                    + ":" + call.getMethodName() + "]");   
  270.                 call = invoke(call);   
  271.                 out = new ObjectOutputStream(socket.getOutputStream());   
  272.                 out.writeObject(call);   
  273.                 out.flush();   
  274.             } catch(Exception e){   
  275.                 e.printStackTrace();   
  276.             } finally{   
  277.                 try{   
  278.                     if(in != null){   
  279.                         in.close();   
  280.                     }   
  281.                     if(out != null){   
  282.                         out.close();   
  283.                     }   
  284.                 } catch(Exception e){   
  285.                 }   
  286.             }   
  287.         }   
  288.     }   
  289.     /**  
  290.      * 调用 call 所指定的的方法  
  291.      * @param call  
  292.      * @return  
  293.      */  
  294.     public Call invoke(Call call){   
  295.         Object obj = map_objs.get(call.getClassName());   
  296.         if(obj == null){   
  297.             try {   
  298.                 obj = Class.forName(call.getClassName()).newInstance();   
  299.                 map_objs.put(call.getClassName(), obj);   
  300.             } catch (Exception e) {   
  301.                 e.printStackTrace();   
  302.             }   
  303.         }   
  304.         try {   
  305.             Method method = obj.getClass().getMethod(   
  306.                             call.getMethodName(),   
  307.                             call.getParamTypes());   
  308.             Object result = method.invoke(obj, call.getParams());   
  309.             call.setResult(result);   
  310.         } catch (Exception e) {   
  311.             e.printStackTrace();   
  312.         }   
  313.         return call;   
  314.     }   
  315.        
  316.     public static void main(String[] args)throws Exception{   
  317.         SimpleServer server = new SimpleServer();   
  318.         server.service();   
  319.     }   
  320. }   
  321.   
  322. // remote.service.HelloServiceImpl.java   
  323. package remote.service;   
  324.   
  325. import java.util.Date;   
  326.   
  327. import share.service.HelloService;   
  328.   
  329. /**  
  330.  *@date 2010-3-13 下午04:30:44  
  331.  *@author dycc  
  332.  *@file remote.service.HelloServiceImpl.java  
  333.  */  
  334. public class HelloServiceImpl implements HelloService{   
  335.     public String echo(String msg) {   
  336.         return "echo:" + msg;   
  337.     }   
  338.     public Date getTime() {   
  339.         return new Date();   
  340.     }   
  341. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现远程调用动态代理接口方法如下: 1. 创建一个接口,其定义需要远程调用方法。 2. 创建一个远程调用的实现,该实现了接口定义的方法。 3. 创建一个动态代理,该实现了接口,并在方法执行时调用远程调用实现的对应方法。 4. 在客户端程序使用动态代理的实例来调用接口方法,实际上是调用远程调用实现方法。 下面是一个实现远程调用动态代理接口的示例代码: ```java // 接口 public interface RemoteInterface { void remoteMethod(); } // 远程调用实现 public class RemoteImpl implements RemoteInterface { @Override public void remoteMethod() { // 远程调用实现 } } // 动态代理 public class RemoteProxy implements InvocationHandler { private Object target; public RemoteProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 远程调用实现方法 method.invoke(target, args); return null; } } // 客户端程序 public class Client { public static void main(String[] args) { RemoteImpl remoteImpl = new RemoteImpl(); RemoteInterface remoteInterface = (RemoteInterface) Proxy.newProxyInstance( RemoteImpl.class.getClassLoader(), RemoteImpl.class.getInterfaces(), new RemoteProxy(remoteImpl) ); remoteInterface.remoteMethod(); } } ``` 在上面的示例代码,我们定义了一个接口 RemoteInterface,并在 RemoteImpl 实现了该接口方法。然后,我们创建了一个动态代理 RemoteProxy,该实现了 InvocationHandler 接口,并在 invoke 方法调用远程调用实现 RemoteImpl 对应的方法。最后,在客户端程序,我们使用 Proxy.newProxyInstance 方法创建了动态代理的实例,并调用了接口方法,实际上是调用远程调用实现方法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值