《深入理解Java Proxy机制.pdf》由会员分享,可在线阅读,更多相关《深入理解Java Proxy机制.pdf(7页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、深入理解 Java Proxy 机制收藏动态代理其实就是 java.lang.reflect.Proxy 类动态的根据您指定的所有接口生成一个class byte,该 class 会继承 Proxy 类,并实现所有你指定的接口您在参数中传入的接口数组;然后再利用您指定的 classloader 将 class byte 加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如 invocationHandler,以即所有的接口对应的Method 成员。初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现你所有的接口的Proxy 对象。请看实例分析:一业务接口类public
2、interface BusinessProcessor public void processBusiness();二 业务实现类public class BusinessProcessorImpl implements BusinessProcessor public void processBusiness()System.out.println(processing business.);三 业务代理类import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class Busine
3、ssProcessorHandler implements InvocationHandler private Object target=null;BusinessProcessorHandler(Object target)this.target=target;public Object invoke(Object proxy,Method method,Object args)throws Throwable System.out.println(You can do something here before process your business);Object result=m
4、ethod.invoke(target,args);System.out.println(You can do something here after process your business);return result;四 客户端应用类import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Proxy;public class Test public static void main(String a
5、rgs)BusinessProcessorImpl bpimpl=new BusinessProcessorImpl();BusinessProcessorHandler handler=new BusinessProcessorHandler(bpimpl);BusinessProcessorbp=(BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(),bpimpl.getClass().getInterfaces(),handler);bp.processBusiness();现在我们看一下打
6、印结果:You can do something here before process your businessprocessing business.You can do something here after process your business通过结果我们就能够很简单的看出Proxy 的作用了,它能够在你的核心业务方法前后做一些你所想做的辅助工作,如log 日志,安全机制等等。现在我们来分析一下上面的类的工作原理。类一二没什么好说的。先看看类三吧。实现了 InvocationHandler 接口的 invoke 方法。其实这个类就是最终 Proxy 调用的固定接口方法。Pro
7、xy 不管客户端的业务方法是怎么实现的。当客户端调用 Proxy 时,它只会调用 InvocationHandler 的 invoke 接口,所以我们的真正实现的方法就必须在invoke 方法中去调用。关系如下:BusinessProcessorImpl bpimpl=new BusinessProcessorImpl();BusinessProcessorHandler handler=new BusinessProcessorHandler(bpimpl);BusinessProcessor bp=(BusinessProcessor)Proxy.newProxyInstance(.);b
8、p.processBusiness()-invocationHandler.invoke()-bpimpl.processBusiness();那么 bp 到底是怎么样一个对象呢。我们改一下main 方法看一下就知道了:public static void main(String args)BusinessProcessorImpl bpimpl=new BusinessProcessorImpl();BusinessProcessorHandler handler=new BusinessProcessorHandler(bpimpl);BusinessProcessorbp=(Busine
9、ssProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(),bpimpl.getClass().getInterfaces(),handler);bp.processBusiness();System.out.println(bp.getClass().getName();输出结果:You can do something here before process your businessprocessing business.You can do something here after process your
10、 business$Proxy0bp 原来是个$Proxy0 这个类的对象。那么这个类到底是长什么样子呢?好的。我们再写二个方法去把这个类打印出来看个究竟,是什么三头六臂呢?我们在main 下面写如下两个静态方法。public static String getModifier(int modifier)String result=;switch(modifier)case Modifier.PRIV ATE:result=private;case Modifier.PUBLIC:result=public;case Modifier.PROTECTED:result=protected;ca
11、se Modifier.ABSTRACT:result=abstract;case Modifier.FINAL:result=final;case Modifier.NA TIVE:result=native;case Modifier.STATIC:result=static;case Modifier.SYNCHRONIZED:result=synchronized;case Modifier.STRICT:result=strict;case Modifier.TRANSIENT:result=transient;case Modifier.VOLATILE:result=volati
12、le;case Modifier.INTERFACE:result=interface;return result;public static void printClassDefinition(Class clz)String clzModifier=getModifier(clz.getModifiers();if(clzModifier!=null&!clzModifier.equals()clzModifier=clzModifier+;String superClz=clz.getSuperclass().getName();if(superClz!=null&!superClz.e
13、quals()superClz=extends +superClz;Class interfaces=clz.getInterfaces();String inters=;for(int i=0;iinterfaces.length;i+)if(i=0)inters+=implements;inters+=interfacesi.getName();System.out.println(clzModifier+clz.getName()+superClz+inters);System.out.println();Field fields=clz.getDeclaredFields();for(
14、int i=0;ifields.length;i+)String modifier=getModifier(fieldsi.getModifiers();if(modifier!=null&!modifier.equals()modifier=modifier+;String fieldName=fieldsi.getName();String fieldType=fieldsi.getType().getName();System.out.println(+modifier+fieldType+fieldName+;);System.out.println();Method methods=
15、clz.getDeclaredMethods();for(int i=0;imethods.length;i+)Method method=methodsi;String modifier=getModifier(method.getModifiers();if(modifier!=null&!modifier.equals()modifier=modifier+;String methodName=method.getName();Class returnClz=method.getReturnType();String retrunType=returnClz.getName();Clas
16、s clzs=method.getParameterTypes();String paraList=(;for(int j=0;jclzs.length;j+)paraList+=clzsj.getName();if(j!=clzs.length-1)paraList+=,;paraList+=);clzs=method.getExceptionTypes();String exceptions=;for(int j=0;jclzs.length;j+)if(j=0)exceptions+=throws;exceptions+=clzsj.getName();if(j!=clzs.length
17、-1)exceptions+=,;exceptions+=;String methodPrototype=modifier+retrunType+methodName+paraList+exceptions;System.out.println(+methodPrototype);System.out.println();再改写 main 方法public static void main(String args)BusinessProcessorImpl bpimpl=new BusinessProcessorImpl();BusinessProcessorHandler handler=n
18、ew BusinessProcessorHandler(bpimpl);BusinessProcessorbp(BusinessProcessor)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(),bpimpl.getClass().getInterfaces(),handler);bp.processBusiness();System.out.println(bp.getClass().getName();Class clz=bp.getClass();printClassDefinition(clz);现在我们再看看输出结果
19、:You can do something here before process your businessprocessing business.You can do something here after process your business$Proxy0java.lang.reflect.Method m4;java.lang.reflect.Method m2;java.lang.reflect.Method m0;java.lang.reflect.Method m3;java.lang.reflect.Method m1;void processBusiness();in
20、t hashCode();boolean equals(java.lang.Object);java.lang.String toString();=很明显,Proxy.newProxyInstance方法会做如下几件事:1,根据传入的第二个参数 interfaces 动态生成一个类,实现 interfaces 中的接口,该例中即BusinessProcessor 接 口 的 processBusiness 方 法。并 且 继 承 了 Proxy 类,重 写 了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyC
21、lass(.);该例中生成了$Proxy0 类2,通过传入的第一个参数classloder 将刚生成的类加载到jvm 中。即将$Proxy0 类 load3,利用第三个参数,调用$Proxy0 的$Proxy0(InvocationHandler)构造函数 创建$Proxy0 的对象,并且用 interfaces 参数遍历其所有接口的方法,并生成 Method 对象初始化对象的几个Method 成员变量4,将$Proxy0 的实例返回给客户端。现在好了。我们再看客户端怎么调就清楚了。1,客户端拿到的是$Proxy0 的实例对象,由于$Proxy0 继承了 BusinessProcessor,因此转化为 BusinessProcessor 没任何问题。BusinessProcessor bp=(BusinessProcessor)Proxy.newProxyInstance(.);2,bp.processBusiness();实际上调用的是$Proxy0.processBusiness();那么$Proxy0.processBusiness()的实现就是通过InvocationHandler 去调用 invoke 方法啦!2009/04/03