動態代理Java實現

來源:互聯網
上載者:User

標籤:int   method   system   water   tar   sele   glib   編譯   log   

思考:在IBuyWatermelon添加一個方法selectWatermelon()

靜態代理中需要在RealSubject中實現該方法,而且Proxy也要實現該方法調用RealSubject中的實現,如果再增加10個方法還是得這樣操作,導致大量的代碼重複。

現在來看動態代理(顧名思義,是在運行時才形成的代理對象,不像靜態代理在編譯時間就載入代理對象)。

產生動態代理的方法有很多: JDK中內建的動態代理java.lang.reflect.*, CGlib等

下面的例子是JDK中內建的動態代理java.lang.reflect.*

 

IBuyWatermelon():介面

package com.maggie.dynamicproxy;public interface IBuyWatermelon {    //代理事件    public abstract String buyWatermelon();        public abstract void selectWatermelon();}

 

BuyWatermelonImpl:實作類別

package com.maggie.dynamicproxy;//可理解成被代理者public class BuyWatermelonImpl implements IBuyWatermelon {    private Supermarket supermaket;        public BuyWatermelonImpl(Supermarket supermaket) {        super();        this.supermaket = supermaket;    }    @Override    public String buyWatermelon() {        System.out.println("在"+supermaket.getName()+" 買西瓜");        return "watermelon";    }    @Override    public void selectWatermelon() {        System.out.println("選擇無籽西瓜");    }}

 

ProxyFactory:代理對象類(核心代碼)

package com.maggie.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyFactory {     //維護一個目標對象    private Object target;    public ProxyFactory(Object target){        this.target=target;    }   //給目標對象組建代理程式對象    public Object getProxyInstance(){        //動態代理的核心,涉及到反射        return Proxy.newProxyInstance(                target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                new InvocationHandler() {                    @Override                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                            //執行目標對象方法                            Object returnValue = method.invoke(target, args);                            return returnValue;                    }                }        );    }}

用戶端調用

package com.maggie.dynamicproxy;public class Main {    public static void main(String[] args) {        Supermarket zhaoLiu = new Supermarket();        zhaoLiu.setName("趙六超市");        IBuyWatermelon target  = new BuyWatermelonImpl(zhaoLiu);//被代理的對象                        //建立代理對象        IBuyWatermelon hourskeeper = (IBuyWatermelon) new ProxyFactory(target).getProxyInstance();                hourskeeper.buyWatermelon();        hourskeeper.selectWatermelon();            }}

輸出

在趙六超市 買西瓜選擇無籽西瓜

 

現在就算IBuyWatermelon的方法再怎麼增加,也只需要在BuyWatermelonImpl實現,就可以在用戶端調用,不會出現大量的重複代碼。

從靜態代理到動態代理都圍繞著賣瓜事件,為了前後方便比較,但是動態代理並沒完,裡面的源碼機制才是核心關鍵

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)這個方法是整個動態代理實現的關鍵

 

動態代理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.