Java動態代理(舉例)

來源:互聯網
上載者:User

     通過JDK實現動態代理,有代理需求的類(這裡稱之為實作類別)必須要實現介面。動態代理可以將邏輯切片,通過代理類(proxy)代實作類別實現邏輯,期間還可以進行一些其他的操作。JDK的動態代理主要涉及到java.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中 InvocationHandler是一個介面,可以通過實現該介面定義橫切邏輯,在並通過反射機制調用目標類的代碼,動態將橫切邏輯和商務邏輯編織在一 起。關於動態這塊兒一直比較迷惑,傻傻分不清楚,今天又有了新的理解,下面通過一個簡單的例子來說明:

   先敘述下事務邏輯:一個人(people對象)通過交通工具(Transportation處理類)去了外國(日本、英國)

  1、將去英國和日本這兩件事當做兩個介面,由人來實現

   

package com.impetention.lei;public interface Japan{   public void goJapan();}--------------------------------------------package com.impetention.lei;public interface England{    public void goEngland();}-------------------------------------------------package com.impetention.lei;//實作類別public class People implements England,Japan{    @Override    public void goEngland()    {        // TODO Auto-generated method stub        System.out.println("I am in England !");    }    @Override    public void goJapan()    {        // TODO Auto-generated method stub        System.out.println("I am in Japan !");    }}

2、現在介紹一下InvocationHandler ,它是代理類的調用處理常式 實現的介面。每個代理類都具有一個關聯的調用處理常式,在執行個體化代理類時會添加進去一個InvocationHandler類型的處理類(完成事務邏輯的主題)。

如:

package com.invocation;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import com.impetention.lei.People;//人通過交通工具(代理)去國外public class Transportation implements InvocationHandler{    //一個叫zhang的人    private Object zhang = null;        public Transportation(Object zhang)    {        this.zhang = zhang;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)     {        // TODO Auto-generated method stub        System.out.println("可以執行一些其他方法.....");        //記錄執行結果        Object result = null;        zhang = new People();        //在zhang對象上執行method方法,並將結果返回        try        {            result = method.invoke(zhang, args);        } catch (Exception e)        {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println("---------------------");        return result;    }}

注意裡面紅色的proxy,它就是代理類執行個體。這裡有必要對invoke(Object proxy, Method method, Object[] args) 做出一些解釋,動態代理類proxy0調用goEngland()方法時會調用它自己的goEngland()方法, 而它自己的goEngland()方法裡面調用的是其綁定對象InvocationHandler對象的invoke()方法, 也就是Transportation的invoke方法。invoke(Object proxy, Method m, Object[] args)種的proxy實際上就是動態代理類proxy, 如果你將其強轉成England然後調用它的goEngland()方法,它又會觸發代理類的goEngland()方法,代理類又調用InvocationHandler(transportation)的invoke()方法,這樣就會死迴圈。

 

 3、代理實現:

package com.main;import java.lang.reflect.Proxy;import com.impetention.lei.England;import com.impetention.lei.Japan;import com.impetention.lei.People;import com.invocation.Transportation;public class Peopletest{    public static void main(String[] args)    {        //準備用動態代理實現,一個叫li的人通過交通工具到了英國        England li = new People();        //執行個體化transportation對象        Transportation t1 = new Transportation(li);        //通過li.getClass().getClassLoader()實作類別的類載入器和li.getClass().getInterfaces()實作類別實現的所有介面作為參數調用                 
//Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces)的方法返回代理類的java.lang.Class對象獲得了一個proxy代理類,
//必須給它一個InvocationHandler參數,也就是我們自己實現的用來在代理類方法執行前後做額外工作的類transpotation。將代理類強轉成England類型
England proxy = (England) Proxy.newProxyInstance(li.getClass().getClassLoader(),                li.getClass().getInterfaces(), t1);        proxy.goEngland();        //準備用動態代理實現,一個叫li的人通過交通工具到了英國                Japan lei = new People();                //執行個體化transportation對象                Transportation t2 = new Transportation(lei);                //通過li.getClass().getClassLoader()和li.getClass().getInterfaces()獲得了一個                //(java.lang.class)proxy代理類,並以tt為參數對其進行執行個體化,強轉成people類型                Japan proxy1 = (Japan) Proxy.newProxyInstance(li.getClass().getClassLoader(),                        li.getClass().getInterfaces(), t2);                proxy1.goJapan();                    }}
小結:過程是這樣的,people執行goEngland()方法不直接執行,而是通過代理類proxy,proxy執行它自己的goEngland(),會觸發Transportation調用invoke(),然後
method.invoke(zhang, args);zhang會調用它的method,即goEngland(),最後將結果返回。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.