動態(tài)代理
這里再簡單總結一下
什么是代理模式,給某個對象提供一個代理對象,并由代理對象控制對于原對象的訪問,即客戶不直接操控原對象,而是通過代理對象間接地操控原對象。
靜態(tài)代理是在程序發(fā)布之前,我們就必須寫好代理類的
動態(tài)代理在程序發(fā)布之前,并沒有寫好代理類,而是發(fā)布之后,動態(tài)創(chuàng)建代理對象的
這篇文章主要介紹兩種動態(tài)代理,jdk代理和cglib代理
jdk代理
實現(xiàn)
通過實現(xiàn) InvocationHandler 接口創(chuàng)建自己的調(diào)用處理器
通過為 Proxy 類指定 ClassLoader 對象和一組 interface 來創(chuàng)建動態(tài)代理類
通過反射機制獲得動態(tài)代理類的構造函數(shù)
通過構造函數(shù)創(chuàng)建動態(tài)代理類實例,構造時調(diào)用處理器對象作為參數(shù)被傳入
代碼
Sale saleProxy=(Sale)Proxy.newProxyInstance( jiajun.getClass().getClassLoader(), jiajun.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("===before==="); Object obj = method.invoke(jiajun, args); System.out.println("===after==="); return obj; } }); saleProxy.sale(); saleProxy.rent();
原理
生成一個代理類,這個代理類繼承Proxy類并且實現(xiàn)了我們定義的接口,代理對象調(diào)用方法的時候,調(diào)用這個代理對象的一個成員InvocationHandler(上面我們傳入了一個InvocationHandler實現(xiàn)對象)的方法,也就是我們添加了before和after后的方法。
cglib代理
實現(xiàn)
實現(xiàn)CGLib包提供的MethodInterceptor接口,實現(xiàn)intercept方法,用CGLib中的Enhancer的creat方法創(chuàng)建代理對象
代碼
class CGLibProxy implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("Before:" + method); Object object = proxy.invokeSuper(obj, arg); System.out.println("After:" + method); return object; } }public class Test2 { public static void main(String[] args) { CGLibProxy cgLibProxy=new CGLibProxy(); Jiajun jiajunProxy=(Jiajun)Enhancer.create(Jiajun.class,cgLibProxy); jiajunProxy.buy(); jiajunProxy.sale(); } }
原理
通過asm字節(jié)碼生成框架生成代理類Class的二進制字節(jié)碼
通過Class.forName加載二進制字節(jié)碼,生成Class對象
通過反射機制獲取實例構造,并初始化代理類對象
jdk代理 vs cglib代理
jdk代理只能代理接口,不能代理沒有接口的類。
cglib代理可以代理沒有接口的類
總結
動態(tài)代理相對于靜態(tài)代理更加靈活,減少了代碼量也提高了可維護性。
動態(tài)代理有兩種,一種是jdk代理,通過創(chuàng)建一個繼承Proxy類并實現(xiàn)接口的代理對象。一種是cglib代理,通過asm生成代理類class的字節(jié)碼,再生成Class對象,最后通過反射創(chuàng)建代理對象。
jdk代理只適合基于接口的代理,cglib可以代理沒有實現(xiàn)接口的目標對象。
我覺得分享是一種精神,分享是我的樂趣所在,不是說我覺得我講得一定是對的,我講得可能很多是不對的,但是我希望我講的東西是我人生的體驗和思考,是給很多人反思,也許給你一秒鐘、半秒鐘,哪怕說一句話有點道理,引發(fā)自己內(nèi)心的感觸,這就是我最大的價值。(這是我喜歡的一句話,也是我寫博客的初衷)
http://www.cnblogs.com/-new/p/7151136.html