【轉(zhuǎn)載】動態(tài)代理兩種實現(xiàn)方式的示例

原文
Spring學(xué)習(xí)(五):動態(tài)代理的兩種實現(xiàn)方式(全網(wǎng)最容易懂)_P@ssW0rd的博客-CSDN博客

1、基于JDK的動態(tài)代理
基于接口的動態(tài)代理,用到的類是Proxy的newProxyInstance靜態(tài)方法創(chuàng)建,要求被代理對象至少實現(xiàn)一個接口,如果沒有,則不能創(chuàng)建代理對象。

2、基于cglib的動態(tài)代理
要導(dǎo)入cglib第三方庫,使用的類是Enhancer的create靜態(tài)方法創(chuàng)建,要求被代理類不能是最終類,即不能用final修飾,如String類。

三、代碼演示
1、首先創(chuàng)建一個IProduct接口,并創(chuàng)建被代理類,實現(xiàn)這個接口
IProduct

public interface IProduct {
    String sell(Float money);
    void afterSell();
}
public class Product implements IProduct {
    @Override
    public String sell(Float money) {
        System.out.println("代理員交給工廠:"+money);
        return "aaa";
    }
    @Override
    public void afterSell() {
        System.out.println("代理員做售后。。");
    }
}

通過JDK來實現(xiàn)動態(tài)代理,創(chuàng)建一個消費者Consumer
這里我們直接通過匿名內(nèi)部類來實現(xiàn),當(dāng)然不是必須的

public class Consumer {
    public static void main(String[] args) {
        // 創(chuàng)建一個被代理對象
        final Product product = new Product();
        // 創(chuàng)建一個代理對象,并在InvocationHandler的invoke方法里面,對被代理類的方法做增強
        IProduct proxyProduct = (IProduct) Proxy.newProxyInstance(product.getClass().getClassLoader(), product.getClass().getInterfaces(), new InvocationHandler() {
            // 實現(xiàn)具體的增強操作           
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 獲取方法在運行中可能產(chǎn)生的返回值
                Object returnValue = null;
                Float money = (Float) args[0];
                if("sell".equals(method.getName())){
                    // 執(zhí)行具體的方法
                    returnValue = method.invoke(product, money*0.8F);
                }
                return returnValue;
            }
        });
        System.out.println(proxyProduct.sell(1000F));
    }
}


IProduct proxyProduct = (IProduct) Proxy.newProxyInstance(product.getClass().getClassLoader(), product.getClass().getInterfaces(), new InvocationHandler() {
}

ClassLoader loader獲取被代理類的類加載器。
Class<?>[] interfaces獲取被代理類的實現(xiàn)接口的數(shù)組。
InvocationHandler h在invok方法中對方法做增強處理。

invoke方法的三個參數(shù)

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
}
3、通過cglib來實現(xiàn)動態(tài)代理,創(chuàng)建一個消費者Consumer

public class Consumer {
    public static void main(final String[] args) {
        // 創(chuàng)建一個被代理對象,這里要求必須是final
        final Product product = new Product();
        Product proxyProduct =(Product) Enhancer.create(product.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Float money = (Float) objects[0];
                Object returnValue = null;
                if("sell".equals(method.getName())){
                    returnValue = method.invoke(product, 0.8f * money);
                }
                return returnValue;
            }
        });
        System.out.println(proxyProduct.sell(1000f));
    }
}

Enhancer.create的2個參數(shù)

Product proxyProduct =(Product) Enhancer.create(product.getClass(), new MethodInterceptor() {
}

Class type被代理類的class文件
Callback callback一個Callback接口,我們通常使用MethodInterceptor接口,繼承了Callback接口
ntercept方法的參數(shù)

public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
}

Method method當(dāng)前方法
Object[] objects方法用到的參數(shù)數(shù)組

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容