java 動態代理

來源:互聯網
上載者:User

標籤:

  1. /** 

  2.  * 相親介面 

  3.  *  

  4.  * @author zhengt 

  5.  * @time Jun 3, 2095 3:13:03 PM 

  6.  */  

  7. public interface XiangQinInterface {  

  8.     /** 

  9.      * 相親方法 

  10.      */  

  11.     public void xiangQin();  

  12. }  

  13. /** 

  14.  * 張三相親實作類別 

  15.  *  

  16.  * @author zhengt 

  17.  * @time Jun 3, 2095 3:14:48 PM 

  18.  */  

  19. public class ZhangSanXiangQinInterfaceImpl implements XiangQinInterface {  

  20.     public void xiangQin() {  

  21.         System.out.println("張三去相親,娶個漂亮老婆。");  

  22.     }  

  23. }  

  24. import java.lang.reflect.InvocationHandler;  

  25. import java.lang.reflect.Method;  

  26.   

  27. /** 

  28.  * 相親可是一輩子的大事,相親前要準備一下,打扮得帥氣些。 

  29.  *  

  30.  * @author zhengt 

  31.  * @time Jun 3, 2095 3:15:48 PM 

  32.  */  

  33. public class ReadyInvocationHandler implements InvocationHandler {  

  34.     //相親介面的實作類別,也就是張三相親類  

  35.     private Object zhangSan = null;  

  36.   

  37.     public ReadyInvocationHandler(Object realSubject) {  

  38.         this.zhangSan = realSubject;  

  39.     }  

  40.   

  41.     public Object invoke(Object proxy, Method m, Object[] args) {  

  42.         Object result = null;  

  43.         try {  

  44.             /** 

  45.              * 動態代理類$Proxy0調用xiangQin方法時會調用它自己的xiangQin方法, 

  46.              * 而它自己的xiangQin方法裡面調用的是super.h.invoke(this, , ),也就是父類Proxy的h的invoke方法, 

  47.              * 也就是ReadyInvocationHandler類的invoke方法。 

  48.              * 所以,invoke(Object proxy, Method m, Object[] args)種的proxy實際上就是動態代理類$Proxy0, 

  49.              * 如果你將其強轉成XiangQinInterface然後調用它的xiangQin方法,然後它就會調用super.h.invoke(this, , ),這樣就會死迴圈。 

  50.              */  

  51.             /** 

  52.              * 網上關於這裡最多問題就是Object proxy放在這裡用來做什麼呢?這個我也不知道, 

  53.              * 不過至少我們知道它到底是個什麼東西,具體做什麼用嘛就不得而知了 

  54.              */  

  55.             System.out.println(proxy.getClass().getSimpleName());  

  56.             System.out.println("張三相親前,代理人給他打扮了打扮。");  

  57.             result = m.invoke(zhangSan, args);  

  58.         } catch (Exception ex) {  

  59.             System.exit(1);  

  60.         }  

  61.         return result;  

  62.     }  

  63. }  

  64. import java.lang.reflect.InvocationHandler;  

  65. import java.lang.reflect.Method;  

  66. import java.lang.reflect.Proxy;  

  67.   

  68. /** 

  69.  * 張三來到了婚介所(相親現場),開始相親。 

  70.  *  

  71.  * @author zhengt 

  72.  * @time Jun 3, 2095 3:17:16 PM 

  73.  */  

  74. public class HunJieSuo {  

  75.     public static void main(String args[]) {  

  76.         //先將張三相親這個相親的實作類別執行個體化,也就是得到XiangQinInterface介面的一個執行個體對象  

  77.         XiangQinInterface zhangSan = new ZhangSanXiangQinInterfaceImpl();  

  78.         /** 

  79.          * 得到ZhangSanXiangQinInterfaceImpl這個類的一個代理類,同時為代理類綁定了一個處理類ReadyInvocationHandler。 

  80.          * 聽著很繞口,其實就是每次調用ZhangSanXiangQinInterfaceImpl這個子類的xiangQin方法時, 

  81.          * 不是zhangSan這個ZhangSanXiangQinInterfaceImpl類的執行個體去調用, 

  82.          * 而是這個ZhangSanXiangQinInterfaceImpl的代理類ReadyInvocationHandler去調用它自己的invoke方法, 

  83.          * 這個invoke方法裡呢可以調用zhangSan這個執行個體的xiangQin方法 

  84.          */  

  85.         /** 

  86.          * 在java種怎樣實現動態代理呢 

  87.          * 第一步,我們要有一個介面,還要有一個介面的實作類別,而這個實作類別呢就是我們要代理的對象, 

  88.          * 所謂代理呢也就是在調用實作類別的方法時,可以在方法執行前後做額外的工作,這個就是代理。 

  89.          * 第二步,我們要自己寫一個在要代理類的方法執行時,能夠做額外工作的類,而這個類必須繼承InvocationHandler介面, 

  90.          * 為什麼要繼承它呢?因為代理類的執行個體在調用實作類別的方法的時候,不會調真正的實作類別的這個方法, 

  91.          * 而是轉而調用這個類的invoke方法(繼承時必須實現的方法),在這個方法中你可以調用真正的實作類別的這個方法。 

  92.          * 第三步,在要用代理類的執行個體去調用實作類別的方法的時候,寫出下面兩段代碼。 

  93.          */  

  94.         XiangQinInterface proxy = (XiangQinInterface) Proxy.newProxyInstance(  

  95.                 zhangSan.getClass().getClassLoader(),  

  96.                 zhangSan.getClass().getInterfaces(),  

  97.                 new ReadyInvocationHandler(zhangSan));  

  98.         proxy.xiangQin();  

  99.         /** 

  100.          * 這裡要解釋下中部那段長長的代碼的意思,以及具體做了哪些工作? 

  101.          * 第一,根據zhangSan.getClass().getClassLoader()這個要代理類的類載入器和 

  102.          * zhangSan.getClass().getInterfaces()要代理類所實現的所有的介面 

  103.          * 作為參數調用Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces) 

  104.          * 的方法返回代理類的java.lang.Class對象,也就是得到了java動態產生的代理類$Proxy0的Class對象。 

  105.          * 同時,java還讓這個動態產生的$Proxy0類實現了要代理類的實現的所有介面,並繼承了Proxy介面。 

  106.          * 第二,執行個體化這個動態產生的$Proxy0類的一個執行個體,執行個體化代理類的建構函式為Proxy(InvocationHandler h), 

  107.          * 也就是說要執行個體化這個動態產生的$Proxy0類,必須給它一個InvocationHandler參數,也就是我們自己實現的用來在代理類 

  108.          * 方法執行前後做額外工作的類ReadyInvocationHandler。 

  109.          * 這段代碼Proxy.newProxyInstance(zhangSan.getClass().getClassLoader(),zhangSan.getClass().getInterfaces(),new ReadyInvocationHandler(zhangSan)) 

  110.          * 得到的其實是一個類名叫$Proxy0 extends Proxy implements XiangQinInterface的類。 

  111.          * 第三,將這個$Proxy0類強制轉型成XiangQinInterface類型,調用xiangQin方法。 

  112.          */  

  113.     }  

  114. }  


網上看到一個牛人讀過這個動態代理的原始碼,現把網址留在這裡,希望對網友們有協助。
http://hi.baidu.com/malecu/blog/item/45d4952b31bc0e27d52af17a.html
我靠,0:21了,抽煙睡覺了。

java 動態代理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.