【转】java的反射机制中的动态代理代理(二)--在远程方法调用中运用代理类
2011-05-23 22:12
1226 查看
在远程方法调用中运用代理类
图 SimpleClient通过HelloService代理类调用远程对象的方法
如上图所示,SimpleClient客户端通过HelloService代理类来调用SimpleServer服务器端的
HelloServiceImpl对象的方法。客户端的HelloService代理类也实现了HelloService接口,这可以简化
SimpleClient客户端的编程。对于SimpleClient客户端而言,与远程服务器的通信的细节被封装到HelloService代理类中。
SimpleClient客户端可以按照以下方式调用远程服务器上的HelloServiceImpl对象的方法:
从以上程序代码可以看出,SimpleClient客户端调用远程对象的方法的代码与调用本地对象的方法的代码很相似,由此可以看出,代理类简化了客户端的编程。
Connector类负责建立与远程服务器的连接,以及接收和发送Socket对象。
例 Connector.java
HelloService代理类有两种创建方式:一种方式是创建一个HelloServiceProxy静态代理类,如例程10-18所示;还有一种方式
是创建HelloService的动态代理类,如例程10-19所示ProxyFactory类的静态getProxy()方法就负责创建
HelloService的动态代理类,并且返回它的一个实例。
例程10-18 HelloServiceProxy.java(静态代理类)
例程10-19 ProxyFactory.java(负责创建动态代理类及其实例)
无论HelloService的静态代理类还是动态代理类,都通过Connector类来发送和接收Call对象。ProxyFactory工厂类的
getProxy()方法的第一个参数classType指定代理类实现的接口的类型,如果参数classType的取值为
HelloService.class,那么getProxy()方法就创建HelloService动态代理类的实例。如果参数classType的取
值为Foo.class,那么getProxy()方法就创建Foo动态代理类的实例。由此可见,getProxy()方法可以创建任意类型的动态代理类
的实例,并且它们都具有调用被代理的远程对象的方法的能力。
如果使用静态代理方式,那么对于每一个需要代理的类,都要手工编写静态代理类的源代码;如果使用动态代理方式,那么只要编写一个动态代理工厂类,它就能自动创建各种类型的动态代理类,从而大大简化了编程,并且提高了软件系统的可扩展性和可维护性。
如例程10-20所示的SimpleClient类的main()方法中,分别通过静态代理类和动态代理类去访问SimpleServer服务器上的HelloServiceImpl对象的各种方法。
例程10-20 SimpleClient.java
SimpleClient通过HelloService静态代理类和动态代理类访问远程HelloServiceImpl对象的echo()方法的时序图。
转自: http://developer.51cto.com/art/200702/40215.htm
图 SimpleClient通过HelloService代理类调用远程对象的方法
如上图所示,SimpleClient客户端通过HelloService代理类来调用SimpleServer服务器端的
HelloServiceImpl对象的方法。客户端的HelloService代理类也实现了HelloService接口,这可以简化
SimpleClient客户端的编程。对于SimpleClient客户端而言,与远程服务器的通信的细节被封装到HelloService代理类中。
SimpleClient客户端可以按照以下方式调用远程服务器上的HelloServiceImpl对象的方法:
//创建HelloService代理类的对象 HelloService helloService1=new HelloServiceProxy(connector); //通过代理类调用远程服务器上的HelloServiceImpl对象的方法 System.out.println(helloService1.echo("hello"));
从以上程序代码可以看出,SimpleClient客户端调用远程对象的方法的代码与调用本地对象的方法的代码很相似,由此可以看出,代理类简化了客户端的编程。
Connector类负责建立与远程服务器的连接,以及接收和发送Socket对象。
例 Connector.java
package proxy1; import java.io.*; import java.net.*; import java.util.*; public class Connector { private String host; private int port; private Socket skt; private InputStream is; private ObjectInputStream ois; private OutputStream os; private ObjectOutputStream oos; public Connector(String host,int port)throws Exception{ this.host=host; this.port=port; connect(host,port); } public void send(Object obj)throws Exception{//发送对象 oos.writeObject(obj); } public Object receive() throws Exception{//接收对象 return ois.readObject(); } public void connect()throws Exception{//建立与远程服务器的连接 connect(host,port); } public void connect(String host,int port) throws Exception{ //建立与远程服务器的连接 skt=new Socket(host,port); os=skt.getOutputStream(); oos=new ObjectOutputStream(os); is=skt.getInputStream(); ois=new ObjectInputStream(is); } public void close(){//关闭连接 try{ }finally{ try{ ois.close(); oos.close(); skt.close(); }catch(Exception e){ System.out.println("Connector.close: "+e); } } } }
HelloService代理类有两种创建方式:一种方式是创建一个HelloServiceProxy静态代理类,如例程10-18所示;还有一种方式
是创建HelloService的动态代理类,如例程10-19所示ProxyFactory类的静态getProxy()方法就负责创建
HelloService的动态代理类,并且返回它的一个实例。
例程10-18 HelloServiceProxy.java(静态代理类)
package proxy1; import java.util.Date; public class HelloServiceProxy implements HelloService{ private String host; private int port; public HelloServiceProxy(String host,int port){ this.host=host; this.port=port; } public String echo(String msg)throws RemoteException{ Connector connector=null; try{ connector=new Connector(host,port); Call call=new Call("proxy1.HelloService","echo", new Class[]{String.class},new Object[]{msg}); connector.send(call); call=(Call)connector.receive(); Object result=call.getResult(); if(result instanceof Throwable) throw new RemoteException((Throwable)result); else return (String)result; }catch(Exception e){ throw new RemoteException(e); //把异常都转换为RemoteException }finally{if(connector!=null)connector.close();} } public Date getTime()throws RemoteException{ Connector connector=null; try{ connector=new Connector(host,port); Call call=new Call("proxy1.HelloService", "getTime", new Class[]{}, new Object[]{}); connector.send(call); call=(Call)connector.receive(); Object result=call.getResult(); if(result instanceof Throwable) throw new RemoteException((Throwable)result); else return (Date)result; }catch(Exception e){ throw new RemoteException(e); //把异常都转换为RemoteException }finally{if(connector!=null)connector.close();} } }
例程10-19 ProxyFactory.java(负责创建动态代理类及其实例)
package proxy1; import java.lang.reflect.*; public class ProxyFactory { public static Object getProxy(final Class classType,final String host,final int port){ InvocationHandler handler=new InvocationHandler(){ public Object invoke(Object proxy,Method method,Object args[]) throws Exception{ Connector connector=null; try{ connector=new Connector(host,port); Call call=new Call(classType.getName(), method.getName(), method.getParameterTypes(), args); connector.send(call); call=(Call)connector.receive(); Object result=call.getResult(); if(result instanceof Throwable) throw new RemoteException((Throwable)result); //把异常都转换为RemoteException else return result; }finally{if(connector!=null)connector.close();} } }; return Proxy.newProxyInstance(classType.getClassLoader(), new Class[]{classType}, handler); } }
无论HelloService的静态代理类还是动态代理类,都通过Connector类来发送和接收Call对象。ProxyFactory工厂类的
getProxy()方法的第一个参数classType指定代理类实现的接口的类型,如果参数classType的取值为
HelloService.class,那么getProxy()方法就创建HelloService动态代理类的实例。如果参数classType的取
值为Foo.class,那么getProxy()方法就创建Foo动态代理类的实例。由此可见,getProxy()方法可以创建任意类型的动态代理类
的实例,并且它们都具有调用被代理的远程对象的方法的能力。
如果使用静态代理方式,那么对于每一个需要代理的类,都要手工编写静态代理类的源代码;如果使用动态代理方式,那么只要编写一个动态代理工厂类,它就能自动创建各种类型的动态代理类,从而大大简化了编程,并且提高了软件系统的可扩展性和可维护性。
如例程10-20所示的SimpleClient类的main()方法中,分别通过静态代理类和动态代理类去访问SimpleServer服务器上的HelloServiceImpl对象的各种方法。
例程10-20 SimpleClient.java
package proxy1; import java.io.*; import java.net.*; import java.util.*; public class SimpleClient { public static void main(String args[])throws Exception { //创建静态代理类实例 HelloService helloService1=new HelloServiceProxy("localhost",8000); System.out.println(helloService1.echo("hello")); System.out.println(helloService1.getTime()); //创建动态代理类实例 HelloService helloService2=(HelloService)ProxyFactory. getProxy(HelloService.class,"localhost",8000); System.out.println(helloService2.echo("hello")); System.out.println(helloService2.getTime()); } }
SimpleClient通过HelloService静态代理类和动态代理类访问远程HelloServiceImpl对象的echo()方法的时序图。
转自: http://developer.51cto.com/art/200702/40215.htm
相关文章推荐
- java反射机制(2)- 实践:反射机制+动态代理实现模拟RMI远程方法调用
- Java 反射机制运用实例(动态调用类的方法)
- Java的反射机制---动态调用对象的简单方法
- Java动态代理实现模拟RMI远程方法调用
- 在远程方法调用中运用反射机制
- Java方法的动态调用(采用反射机制)
- 居于反射机制Java动态调用jar方法
- Java的反射机制-动态调用对象的方法
- JAVA反射示例四——结合代理模式的远程方法调用事例
- Java 通过反射机制动态调用java类方法
- 在远程方法调用中运用反射机制
- Java的反射机制和动态代理
- Java反射—运用反射生成jdk动态代理
- java中利用反射机制实现调用给定为字符串的方法名
- 【转】java的反射机制中的动态代理代理(一)--简介
- JAVA 反射 动态调用不同类的静态方法
- java学习之路 之 反射机制综合练习题、动态代理实例
- java 反射机制调用私有构造方法并执行类内方法
- OC反射机制-动态调用方法
- Java300StudyNote(3)-Java动态编译(DynamicCompile)、动态运行、反射调用mian方法、JavaCompiler.run()空指针问题