java 的 Proxy

一 代理类 1.代理类实例和java.lang.reflect.Proxy 代理类一种在运行期创建的,实现指定的一组接口的类可以通过如下方法来获得代理类实例: java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) Object proxyInstance Proxy.newProxyInstance()方法返回一个Object类型的类实例,通常把这样一个实例叫做代理类实例(proxyInstance), 该实例对应的类具有如下特点: 1) 继承了类: java.lang.reflect.Proxy. 2) 实现了一组指定的接口(通过传入的参数Class[] interfaces指定). 3) 类名以”$Proxy”开头. 4) public final,非staticl的举例: 有两个接口Interface1,Interface2 Interface1具有方法m1,Interface2具有方法m21和m22 Class[] interfaces = Class{ Interface 1.class, Interface 2.class}; ClassLoader loader = interface1.class.getClassLoader(); Object pInstance = Proxy.newProxyInstance(loader, interfaces, InvocationHandler h); 这里的实例pInstance的类具有如下形式: Public Final Class $ProxyXXX implements Interface1, Interface2 extends Proxy {……} 由于实例pInstance具有这种形式,故可实现如下的强制类型转换和方法调用: Interface1 interface1Impl = (Interface1)pInstance; interface1Impl.m1(); Interface2 interface2Impl = (Interface2)pInstance; interface1Imp2.m21(); interface1Imp2.m22(); 注意: 代理类实例和JDK的java.lang.reflect.Proxy不是一回事, java.lang.reflect.Proxy有生成具有前述的4个特点的类实例的方法. 2.代理类如何实现代理接口的方法前面一节说明了什么是代理类实例和代理类的形式,但是并没有说明代理类中实现的接口方法是如何实现的. 代理类中实现的接口方法的实现是通过一个实现了java.lang.reflect.InvocationHandler 接口的类(Proxy.newProxyInstance()方法的第三个参数h)来完成的. InvocationHandler 接口的实现类通常会封装接口的实现类,并且在接口InvocationHandler具有的invoke()方法中编写对这些接口方法的调用逻辑. 举例: 沿用前面的例子,假设实现如下功能: 在调用接口Interface1的方法时,采用Interface1接口实现类Interface1Impl1实现 public class Interface1Impl implements Interface1 { public Interface1Impl() { } public void m1() { System.out.println("Calling Interface1Impl.m1()"); } } 在调用接口Interface2的方法时,不采用任何Interface2接口实现类实现,只是打印出字符串”this is Interface2’s Method” InvocationHandler 接口的实现类可以这样写: public class InvocationHandlerImpl implements InvocationHandler { Interface1 interface1Impl; ---------- 封装Interface1的实现类 public InvocationHandlerImpl(Interface1 l_interface1ImplInstance) { this.interface1Impl = l_interface1ImplInstance; } public Object invoke(Object l_proxy, Method l_method, Object[] l_args) throws Throwable ---------- 实现InvocationHandler接口的方法 { System.out.println("Starting Calling on InvocationHandlerImpl.invoke"); Class l_declaringClass = l_method.getDeclaringClass(); if (l_declaringClass == Interface1.class) 利用反射机制判断调用方法l_method的来源 { l_method.invoke(interface1Impl, l_args); } else if (l_declaringClass == Interface2.class) { System.out.println("this is Interface2’s Method"); 根据方法来源,采用不同实现方式 } System.out.println("Ending Calling on InvocationHandlerImpl.invoke"); return null; } } 测试程序如下: Interface1 l_interface1Impl = new Interface1Impl(); InvocationHandler l_h = new InvocationHandlerImpl(l_interface1Impl); 生成InvocationHandler接口实现类的实例 Object l_obj = Proxy.newProxyInstance(Interface1.class.getClassLoader(), 生成代理类的实例 new Class[]{Interface1.class, Interface2.class}, l_h); //Calling on Interface1's method by proxyInstance:l_obj Interface1 l_interface1Proxy = (Interface1)l_obj; l_interface1Proxy.m1(); System.out.println("-----------------------------------------------"); //Calling on Interface2's method by proxyInstance:l_obj Interface2 l_interface2Proxy = (Interface2)l_obj; l_interface2Proxy.m21(); 调用接口方法 System.out.println("-----------------------------------------------"); l_interface2Proxy.m22(); 结果: Starting Calling on InvocationHandlerImpl.invoke Calling Interface1Impl.m1() Ending Calling on InvocationHandlerImpl.invoke ----------------------------------------------- Starting Calling on InvocationHandlerImpl.invoke this is Interface2’s Method Ending Calling on InvocationHandlerImpl.invoke ----------------------------------------------- Starting Calling on InvocationHandlerImpl.invoke this is Interface2’s Method Ending Calling on InvocationHandlerImpl.invoke 4.代理类的实质使用代理类的调用流程接口方法调用-----------代理类的invoke方法---------接口方法的实现(由接口实现类或其他方式提供) 不使用代理类的调用流程接口方法调用-----------接口方法的实现(由接口实现类提供) 二.Interceptor机制 如图,XTrade的Interceptor机制要实现一个Service接口有一个与之对应的接口实现类ServiceImpl. 特殊地, XTrade要求具有在调用接口实现类的接口方法之前(onCall),之后(onReturn)和异常(onthrowable)的时候做一些处理的能力. 因此,这里采用代理机制来代理Service接口,把接口实现类ServiceImpl和调用接口实现类的接口方法前后及出错时的处理封装到代理类的InvocationHandler接口实现类中,并且在InvocationHandler接口方法(invoke)编写实现类接口方法和调用方法前后处理,即Interceptor机制. 如下程序: private static class Manager implements Interceptable { private Object _flddelegate; Service接口实现类ServiceImpl private Interceptor array[]; Service接口方法前后及出错时的处理,即Interceptor实现类的实例数组 public void addInterceptor(Interceptor i) Interceptable接口的方法,用于往array数组中追加Interceptor实现类 {……} private Manager(Object delegate)  用于封装Service接口实现类ServiceImpl { …… _flddelegate = delegate; …… } private Object invoke(Method method, Object args[]) throws Throwable { int n = interceptors.length; int i = n; try { while(--i >= 0) { interceptors[i].onCall(); 调用接口方法前的处理 } Object result = InterceptableBuilder.invokeOn(_flddelegate, method, args); 利用反射机制调用接口方法 while(++i < n) { interceptors[i].onReturn(); 调用接口方法后的处理 } return result; } catch(Throwable rootCause) { latest = rootCause; } while(++i < n) { try { interceptors[i].onThrowable(); 调用接口方法出错后的处理 } catch(Throwable otherProblem) { latest = otherProblem; } } throw latest;     } } InvocationHandler接口实现类: private static class InvocationHandlerImpl implements InvocationHandler { private Manager manager; public Object invoke(Object proxy, Method method, Object args[])  <――――InvocationHandler接口方法的实现 throws Throwable { if(method.getDeclaringClass() == (Interceptable.class))       <――――根据方法的接口来源,进行不同处理 return InterceptableBuilder.invokeOn(manager, method, args)         else return manager.invoke(method, args); }     ...... } 通过如下方式使用: 举例:接口ServiceA,接口方法为methodA ServiceA的实现类ServiceAImpl Interceptor实现类:InterceptorImpl1,InterceptorImpl2 1) 生成与Service接口对应的代理类实例(把Service接口和Service接口注册在一起) Object implementation = new ServiceAImpl(); Manager manager = new Manager(implementation);            <――――― 生成InvocationHandler接口实现类 InvocationHandler handler = new InvocationHandlerImpl(manager); Class clientInterface = ServiceA.Class; Object proxy = Proxy.newProxyInstance(clientInterface.getClassLoader(), new Class[] {clientInterface, Interceptable.class}, handler);   <――――― 生成实现接口ServiceA和Interceptable的代理类实例 2) 追加Interceptor实现类  Interceptor interceptor1 = InterceptorImpl1(); Interceptor interceptor2 = InterceptorImpl2();   Interceptable interceptable = (Interceptable)proxy;     <――――― 利用代理机制追加Interceptor实现类 interceptable.addInterceptor(interceptor1); interceptable.addInterceptor(interceptor2); 3)使用接口ServiceA的方法 ServiceA service = (ServiceA)proxy; service.methodA();                      <――――― 利用代理机制调用ServiceA接口方法,并且实现方法调用前后处理.
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页