小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

jdk動(dòng)態(tài)代理和cglib代理總結(jié)

 SparkStreaming 2015-10-07

首先我們來(lái)談?wù)刯dk的動(dòng)態(tài)代理,它允許開發(fā)者在運(yùn)行期創(chuàng)建接口的代理實(shí)例,那么當(dāng)我們?cè)谶\(yùn)行過(guò)程中調(diào)用某個(gè)實(shí)例的某個(gè)方法時(shí),可以使用代理對(duì)象去具體實(shí)現(xiàn)它,從而達(dá)到aop的效果。

(1)jdk的動(dòng)態(tài)代理主要涉及兩個(gè)類:proxy和invocacationHandler,invocationHandler里面包含了橫切邏輯,并且可以使用反射調(diào)用目標(biāo)類的方法(就是切點(diǎn)),proxy類主要是使用它的一個(gè)newinstance方法去創(chuàng)建一個(gè)代理實(shí)例。

下面我們來(lái)看代碼:

  1. package com.yue.test;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5.   
  6. public class testHandler implements InvocationHandler{  
  7.     private Object target;  
  8.     public testHandler(Object o){  
  9.         this.target  = o;  
  10.     }  
  11.       
  12.     /*  
  13.      * 這里的method對(duì)象是java反射機(jī)制中的方法反射類對(duì)象,通過(guò)這個(gè)方法反射對(duì)象可以調(diào)用目標(biāo)對(duì)象中的方法  
  14.      * 里面的target是目標(biāo)類對(duì)象,利用反射在目標(biāo)類對(duì)象中找到對(duì)應(yīng)的方法傳入?yún)?shù)后調(diào)用  
  15.      * 也可以說(shuō)是根據(jù)目標(biāo)對(duì)象得到的代理對(duì)象是在目標(biāo)對(duì)象的基礎(chǔ)上插入了橫切邏輯的  
  16.      * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])  
  17.      */  
  18.     @Override  
  19.     public Object invoke(Object proxy, Method method, Object[] args)  
  20.             throws Throwable {  
  21.         System.out.println("hey");  
  22.         Object obj = method.invoke(target, args);  
  23.         System.out.println("end!");  
  24.         return obj;  
  25.     }  
  26.   
  27. }  

  1. package com.yue.test;  
  2.   
  3.   
  4.   
  5. public class PrivateCar implements Car{  
  6.       
  7.       
  8.     public void say(){  
  9.         System.out.println("spring is fun!");  
  10.     }  
  11. }  

  1. package com.yue.test;  
  2.   
  3. public interface Car {  
  4.     public void say();  
  5. }  

  1. package com.yue.test;  
  2.   
  3. import java.lang.reflect.Proxy;  
  4.   
  5.   
  6.   
  7.   
  8. public class Test {  
  9.   
  10.     public static void main(String[] args){  
  11.         PrivateCar pc = new PrivateCar();  
  12.         testHandler th = new testHandler(pc);  
  13.         //這里因?yàn)樯傻拇韺?duì)象實(shí)現(xiàn)了目標(biāo)對(duì)象的所有接口,所以根據(jù)多態(tài)可以變?yōu)镃ar類型  
  14.         Car car = (Car)Proxy.newProxyInstance(pc.getClass().getClassLoader(), pc.getClass().getInterfaces(), th);  
  15.         car.say();  
  16.           
  17.       
  18.     }  
  19.   
  20.   
  21. }  

得到的結(jié)果是:

  1. hey  
  2. spring is fun!  
  3. end!  

所以我們可以看到,jdk動(dòng)態(tài)代理的局限在于它只是在接口層次上的實(shí)現(xiàn),不能用在子類上

(2)若要不是用于接口定義,則需要用到cglib代理(這里需要格外引入jar包)

cglib代理使用底層的字節(jié)碼技術(shù),可以為一個(gè)類創(chuàng)建子類,并在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用,織入橫切邏輯

下面我們來(lái)看看代碼:

  1. package com.yue.test;  
  2.   
  3.   
  4.   
  5.   
  6.   
  7. public class Test {  
  8.   
  9.     public static void main(String[] args){  
  10.         CglibProxy cp = new CglibProxy();  
  11.         PrivateCar pc = (PrivateCar)cp.getProxy(PrivateCar.class);  
  12.         pc.say();  
  13.     }  
  14.   
  15.   
  16. }  

  1. package com.yue.test;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import net.sf.cglib.proxy.Enhancer;  
  6. import net.sf.cglib.proxy.MethodInterceptor;  
  7. import net.sf.cglib.proxy.MethodProxy;  
  8.   
  9. public class CglibProxy implements MethodInterceptor{  
  10.     private Enhancer enhancer = new Enhancer();  
  11.     /*  
  12.      * 這里的setSuperClass表示創(chuàng)建的代理對(duì)象是這個(gè)類的子類  
  13.      * create方法表示使用字節(jié)碼的方式創(chuàng)建子類對(duì)象  
  14.      */  
  15.     public Object getProxy(Class clazz){  
  16.         enhancer.setSuperclass(clazz);  
  17.         enhancer.setCallback(this);  
  18.         return enhancer.create();  
  19.     }  
  20.       
  21.     /*  
  22.      * 每個(gè)父類方法的調(diào)用,都會(huì)被這個(gè)intercept方法攔截住,并且織入橫切邏輯  
  23.      * 這里的methodProxy對(duì)象也是利用java的反射機(jī)制去執(zhí)行父類中的業(yè)務(wù)方法  
  24.      * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)  
  25.      */  
  26.     @Override  
  27.     public Object intercept(Object arg0, Method arg1, Object[] arg2,  
  28.             MethodProxy arg3) throws Throwable {  
  29.         System.out.println("heycglib");  
  30.         Object obj = arg3.invokeSuper(arg0, arg2);  
  31.         return obj;  
  32.     }  
  33.   
  34. }  

總結(jié):由于cglib代理創(chuàng)建代理對(duì)象時(shí)間比jdk代理多了差不多8倍,而創(chuàng)建出來(lái)的代理運(yùn)行速率差不多是jdk創(chuàng)建出來(lái)的10倍,所以一般單例我們都使用cglib代理,prototype就是用jdk代理


這里我們還必須注意的是,因?yàn)閖dk動(dòng)態(tài)代理是使用接口創(chuàng)建,cglib動(dòng)態(tài)代理創(chuàng)建的是子類代理,所以:

(1)jdk:除public外的所有方法都不可以被增強(qiáng)(注意public static也是不可以的)

(2)cglib:private,static、final方法都不可以


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多