按照代理類的創(chuàng)建時(shí)期,代理類可分為兩種。
l 靜態(tài)代理類:由程序員創(chuàng)建或由特定工具自動(dòng)生成
源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。
l 動(dòng)態(tài)代理類:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。

可以看出靜態(tài)代理類有一個(gè)很不爽的缺點(diǎn):當(dāng)如果接口加一個(gè)方法(把上面所有的代碼的注釋給去掉),所有的實(shí)現(xiàn)類和代理類里都需要做個(gè)實(shí)現(xiàn)。這就增加了代碼的復(fù)雜度。動(dòng)態(tài)代理就可以避免這個(gè)缺點(diǎn)。

3 。動(dòng)態(tài)代理

動(dòng)態(tài)代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到一個(gè)集中的方法中處理(invoke),這樣,在接口方法數(shù)量比較多的時(shí)候,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個(gè)方法進(jìn)行中轉(zhuǎn)。

動(dòng)態(tài)代理只能代理接口代理類都需要實(shí)現(xiàn)InvocationHandler類,實(shí)現(xiàn)invoke方法。該invoke方法就是調(diào)用代理接口的所有方法時(shí)需要調(diào)用的,該invoke方法返回的值是代理接口的一個(gè)實(shí)現(xiàn)類

代碼實(shí)例:
  1. package ttitfly.proxy;       
  2.       
  3. import java.lang.reflect.InvocationHandler;       
  4. import java.lang.reflect.Method;       
  5. import java.lang.reflect.Proxy;       
  6. //動(dòng)態(tài)代理類只能代理接口,代理類都需要實(shí)現(xiàn)InvocationHandler類,實(shí)現(xiàn)invoke方法。該invoke方法就是調(diào)用被代理接口的所有方法時(shí)需要調(diào)用的,該invoke方法返回的值是被代理接口的一個(gè)實(shí)現(xiàn)類       
  7. public class DynamicProxy implements InvocationHandler{       
  8.            
  9.     private Object object;        
  10.     //綁定關(guān)系,也就是關(guān)聯(lián)到哪個(gè)接口(與具體的實(shí)現(xiàn)類綁定)的哪些方法將被調(diào)用時(shí),執(zhí)行invoke方法。   
  11.     //Proxy.newProxyInstance的第三個(gè)參數(shù)是表明這些被攔截的方法執(zhí)行時(shí)需要執(zhí)行哪個(gè)InvocationHandler的invoke方法   
  12.     public Object bindRelation(Object object){        
  13.         this.object = object;       
  14.         return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);        
  15.     }        
  16.     //攔截關(guān)聯(lián)的這個(gè)實(shí)現(xiàn)類的方法被調(diào)用時(shí)將被執(zhí)行       
  17.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
  18.         System.out.println("Welcome");       
  19.         Object result = method.invoke(object, args);        
  20.         return result;       
  21.     }       
  22.       
  23. }       


 

測(cè)試類:

java 代碼
  1. package ttitfly.proxy;       
  2.       
  3. public class TestDynamicProxy {       
  4.     public static void main(String[] args){       
  5.         HelloWorld helloWorld = new HelloWorldImpl();       
  6.         DynamicProxy dp = new DynamicProxy();       
  7.         //在這里綁定的是HelloWorld,也就是HelloWorld是被代理接口。所以綁定關(guān)系時(shí),需要傳遞一個(gè)HelloWorld的實(shí)現(xiàn)類的實(shí)例化對(duì)象。       
  8.         HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);        
  9.         helloWorld1.print();        
  10.         helloWorld1.say();       
  11.            
  12.         //helloWorld2將不被攔截   
  13.         HelloWorld helloWorld2 = new HelloWorldImpl();   
  14.         helloWorld2.print();        
  15.         helloWorld2.say();   
  16.            
  17.     }       
  18. }       


------君臨天下,舍我其誰------