Java动态代理简述

         JDK自1.3版本开始,引用了动态代理。这真是对小弟我这种懒人的福音啊O(∩_∩)O哈哈~,不过,到现在都基本木用到~~~~(>_<)~~~~ !
         不管了,现瞎整理一下,各位大虾不要见笑哈!
 
一、 Java 动态代理
         先移一张代理模式的图过来,如下:

         Java提供的动态代理呢,就差不多这个原理啦(貌似啥都没说⊙﹏⊙b汗)!它呢,使得我们开发人员能可以手动指定一组接口或委托类对象,来动态获得代理类ProxySubject。ProxySubject在替RealSubject doSomething()的同时,可以去doOtherthing()。也就是负责委派任务同时按需做些其他偷鸡摸狗的事。
 
         动态代理相关的类和接口,被定义在java.lang.reflect包内:Proxy和InvocationHandler。可以看下API手册对它们所作的介绍,有讲到代理类如何创建、代理类属性等,小弟就不多做介绍了,直接动手操作啦^_^!
 
         操作步骤很简单,两步。一、实现InvocationHandler接口,在重写的invoke(…)方法内处理代理类方法并返回结果;二、直接用Proxy的newProxyInstance(…)静态方法,返回代理类实例,执行方法。
         具体实现参照小弟提供附件Java工程的org.join.proxy.origin包,是一个代理执行方法计算执行时间的小例子。(觉着贴代码,文档稍有点冗余╮(╯▽╰)╭)
 
         不过呢,Java提供的Proxy只支持Interface,也就是我们的代理对象是实现一个或多个接口的,处理的呢是接口定义的方法,泪啊!
 
二、 Java 动态代理扩展
         哼哼,想天下高人何其多哉!Java的动态代理不能摆脱Interface的桎梏,我们自个扩展还不成吗!
         小弟如愿以偿地找到了这么两篇文章:Java 动态代理机制分析及扩展,第 1 部分;Java 动态代理机制分析及扩展,第 2 部分。还请各位大虾自己搜下,原出处是IBM的。看人家写的,啧啧,看来我就是个打酱油的T^T!
         第一篇是Java动态代理机制,第二篇才讲述了动态代理的扩展。偷偷摘点下来,好邪恶^_^。这些在ProxyEx类注释里都有(附件工程内)。
 
         ProxyEx直接继承于java.lang.reflect.Proxy,也声明了与原Proxy类中同名的public静态方法,目的是保持与原代理机制在使用方法上的完全一致。
         与原代理机制最大的区别在于,动态生成的代理类将不再从Proxy类继承,改而继承需被代理的类。由于Java的单继承原则,扩展代理机制所支持的类数目不得多于一个,但它可以声明实现若干接口。包管理的机制与原来相似,不支持一个以上的类和接口同时为非public;如果仅有一个非public的类或接口,假设其包为PackageA,则动态生成的代理类将位于包PackageA;否则将位于被代理的类所在的包。生成的代理类也被赋予final和public访问属性,且其命名规则类似地为“父类名+ProxyN”(N 也是递增的阿拉伯数字)。最后,在异常处理方面则与原来保持完全一致。
         受限于 Java 的类继承机制,扩展的动态代理机制也有其局限,它不能支持:

         1. 声明为 final 的类;

         2. 声明为 final 的函数;

         3. 构造函数均为 private 类型的类;

 
         那具体实现可行吗?小弟依样画葫芦,做了两个类,定义在org.join.proxy。ProxyClassFactory:用于生产整个代理类的描述;ProxyEx:从接口扩展到类的动态代理机制实现类。
         附件工程org.join.proxy.extend包内,就是具体使用了。ProxyClassFactoryTest是ProxyClassFactory的测试类,其他3个执行TicketBuyer(原文档的例子)。
         别忘了导入JDK目录下lib内的tools.jar。对于没看到这句,看见红叉叉不能运行,在背后问候那啥的,我只能先深深报以鄙视。
 
三、 CGlib 动态代理实现
         噜噜,想必大虾们,对此都比较了解!再偷偷摘段别人的介绍:CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
         CGlib被许多AOP框架所使用,如Spring啥的。Hibernate现在好像有自己的CGlib库了,说错了别打我啊,小弟对这个不了解了!CGlib所做的呢,是由asm所提供的,即是对Java字节码的操作!这两个相关地址如下:
         CGlib:http://sourceforge.net/projects/cglib/files/
         ASM:http://forge.ow2.org/projects/asm
         地址具体是啥,也不太清楚,应该是下载地址吧,很久以前的记录了。如果失效了,只能说声‘悲了个催’,O(∩_∩)O哈哈~!
 
         用CGlib怎么进行动态代理呢,还是一样的例子,看一个方法的执行时间。一样的,参见附件工程org.join.proxy.cglib包。
         工程需要导入cglib-nodep-2.2.2.jar包就成,nodep貌似是no depend,无依赖!
 
         CGlib用于代理未实现接口的类,其是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调用用户定义的拦截方法。
         步骤概括下:一、继承MethodInterceptor接口实现一个方法拦截器,用于Callback。二、创建Enhancer,setSuperclass设置代理类类型,setCallback设置回调接口,create()创建代理子类,子类转成代理类执行方法。
 
四、后记
         小弟在家没网,只是写个文档罢了,一些参考文章不能给出网址,还望见谅T^T!