按照代理類的創建時期,代理類可分為兩種。
l 靜態代理類:由程序員創建或由特定工具自動生成
源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。
l 動態代理類:在程序運行時,運用反射機制動態創建而成。

可以看出靜態代理類有一個很不爽的缺點:當如果接口加一個方法(把上面所有的代碼的注釋給去掉),所有的實現類和代理類里都需要做個實現。這就增加了代碼的復雜度。動態代理就可以避免這個缺點。

3 。動態代理

動態代理與普通的代理相比較,最大的好處是接口中聲明的所有方法都被轉移到一個集中的方法中處理(invoke),這樣,在接口方法數量比較多的時候,我們可以進行靈活處理,而不需要像靜態代理那樣每一個方法進行中轉。

動態代理只能代理接口代理類都需要實現InvocationHandler類,實現invoke方法。該invoke方法就是調用代理接口的所有方法時需要調用的,該invoke方法返回的值是代理接口的一個實現類

代碼實例:
  1. package ttitfly.proxy;       
  2.       
  3. import java.lang.reflect.InvocationHandler;       
  4. import java.lang.reflect.Method;       
  5. import java.lang.reflect.Proxy;       
  6. //動態代理類只能代理接口,代理類都需要實現InvocationHandler類,實現invoke方法。該invoke方法就是調用被代理接口的所有方法時需要調用的,該invoke方法返回的值是被代理接口的一個實現類       
  7. public class DynamicProxy implements InvocationHandler{       
  8.            
  9.     private Object object;        
  10.     //綁定關系,也就是關聯到哪個接口(與具體的實現類綁定)的哪些方法將被調用時,執行invoke方法。   
  11.     //Proxy.newProxyInstance的第三個參數是表明這些被攔截的方法執行時需要執行哪個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.     //攔截關聯的這個實現類的方法被調用時將被執行       
  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. }       


 

測試類:

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是被代理接口。所以綁定關系時,需要傳遞一個HelloWorld的實現類的實例化對象。       
  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. }       


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