欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java動態(tài)代理的示例詳解

 更新時(shí)間:2022年02月23日 17:17:43   作者:溫故知新之java  
動態(tài)代理指的是,代理類和目標(biāo)類的關(guān)系在程序運(yùn)行的時(shí)候確定的,客戶通過代理類來調(diào)用目標(biāo)對象的方法,是在程序運(yùn)行時(shí)根據(jù)需要動態(tài)的創(chuàng)建目標(biāo)類的代理對象。本文將通過案例詳細(xì)講解一下動態(tài)代理,需要的可以參考一下

定義

動態(tài)代理指的是,代理類和目標(biāo)類的關(guān)系在程序運(yùn)行的時(shí)候確定的,客戶通過代理類來調(diào)用目標(biāo)對象的方法,是在程序運(yùn)行時(shí)根據(jù)需要動態(tài)的創(chuàng)建目標(biāo)類的代理對象。

分類

jdk動態(tài)代理

cglib動態(tài)代理

案例

需求

蘋果公司通過蘋果代理商來賣手機(jī)

方案一:jdk動態(tài)代理

定義抽象接口

/**
 * 售賣手機(jī)的接口(代理模式——抽象角色)
 * @author:liyajie
 * @createTime:2022/2/22 14:42
 * @version:1.0
 */
public interface IPhone {

    /**
     * 出售手機(jī)
     * @author: liyajie
     * @date: 2022/2/22 14:44
     * @param
     * @return void
     * @exception:
     * @update:
     * @updatePerson:
     **/
    void sellPhone();
}

定義目標(biāo)類實(shí)現(xiàn)接口,重寫接口方法

/**
 * 蘋果公司(代理模式——目標(biāo)角色)
 * @author:liyajie
 * @createTime:2022/2/22 14:46
 * @version:1.0
 */
public class TargetPhone implements IPhone {
    @Override
    public void sellPhone() {
        System.out.println("蘋果公司正在出售手機(jī)");
    }
}

定義代理類

/**
 * 代理商(代理模式——代理角色)
 * @author:liyajie
 * @createTime:2022/2/22 14:50
 * @version:1.0
 */
public class ProxyPhone {

    private Object target;

    public ProxyPhone(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 {
                        System.out.println("JDK動態(tài)代理開始之前,添加業(yè)務(wù)邏輯XXX");
                        //使用反射機(jī)制來調(diào)用目標(biāo)對象的方法:解決了問題二
                        Object invoke = method.invoke(target, args);
                        System.out.println("JDK動態(tài)代理結(jié)束之后,添加業(yè)務(wù)邏輯XXX");
                        return invoke;
                    }
                });
    }
}

定義測試類

/**
 * 測試類
 * @author:liyajie
 * @createTime:2022/2/23 15:15
 * @version:1.0
 */
public class Test {
    public static void main(String[] args) {
        // 創(chuàng)建目標(biāo)類
        TargetPhone targetPhone = new TargetPhone();
        // 創(chuàng)建代理類
        IPhone iPhone = (IPhone) new ProxyPhone(targetPhone).getProxyInstance();
        System.out.println(iPhone.getClass());
        // 通過代理類調(diào)用目標(biāo)方法
        iPhone.sellPhone();
    }
}

查看測試結(jié)果

方案二:cglib動態(tài)代理

定義目標(biāo)類

/**
 * 蘋果公司(代理模式——目標(biāo)角色)
 * @author:liyajie
 * @createTime:2022/2/22 14:46
 * @version:1.0
 */
public class TargetPhone {

    public void sellPhone() {
        System.out.println("蘋果公司正在出售手機(jī)");
    }
}

定義代理工廠,用來獲取代理類

/**
 * 代理工廠
 * @author:liyajie
 * @createTime:2022/2/23 15:32
 * @version:1.0
 */
public class ProxyFactory implements MethodInterceptor {

    private Object target;

    public ProxyFactory(Object target){
        this.target = target;
    }

    public Object getProxyInstance(){
        // 創(chuàng)建一個(gè)工具類
        Enhancer enhancer = new Enhancer();
        // 設(shè)置父類
        enhancer.setSuperclass(target.getClass());
        // 設(shè)置回調(diào)函數(shù)
        enhancer.setCallback(this);
        // 創(chuàng)建子類對象,即代理對象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib動態(tài)代理開始之前,添加業(yè)務(wù)邏輯xxxx");
        Object invoke = method.invoke(target, objects);
        System.out.println("cglib動態(tài)代理之后,添加業(yè)務(wù)邏輯");
        return invoke;
    }
}

定義測試類

/**
 * 測試類
 * @author:liyajie
 * @createTime:2022/2/23 15:44
 * @version:1.0
 */
public class Test {
    public static void main(String[] args) {
        // 創(chuàng)建目標(biāo)對象
        TargetPhone targetPhone = new TargetPhone();
        // 獲取代理對象
        TargetPhone proxyInstance = (TargetPhone)new ProxyFactory(targetPhone).getProxyInstance();
        // 通過代理對象調(diào)用具體的方法
        proxyInstance.sellPhone();
    }
}

查看測試結(jié)果

分析

首先可以看到不管是jdk動態(tài)代理,還是cglib動態(tài)代理,實(shí)現(xiàn)的效果和靜態(tài)代理是一模一樣的,都實(shí)現(xiàn)了功能的擴(kuò)展。但是兩種動態(tài)代理還是有些不同的,其中jdk動態(tài)代理需要目標(biāo)對象實(shí)現(xiàn)接口,但是cglib動態(tài)代理不需要,因?yàn)樗窃趦?nèi)存中構(gòu)建一個(gè)子類對象,從而實(shí)現(xiàn)對目標(biāo)對象的功能擴(kuò)展。

總結(jié)

通過案例,我們了解了代理模式的幾種實(shí)現(xiàn)方式,下面我們總結(jié)下該模式:

優(yōu)勢:

  • 代理模式在客戶端和目標(biāo)對象之間起到了一個(gè)中介和保護(hù)的作用
  • 代理對象可以對目標(biāo)對象進(jìn)行功能的擴(kuò)展和業(yè)務(wù)的擴(kuò)展,增強(qiáng)目標(biāo)對象
  • 代理模式可以將客戶端和目標(biāo)對象分離,在一定程度上降低了系統(tǒng)的耦合度

劣勢:

  • 請求需要經(jīng)過代理對象,會導(dǎo)致處理速度變慢
  • 因?yàn)闀写罅康拇韺ο螽a(chǎn)生,會增加系統(tǒng)的復(fù)雜度

到此這篇關(guān)于Java動態(tài)代理的示例詳解的文章就介紹到這了,更多相關(guān)Java 動態(tài)代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java操作MongoDB數(shù)據(jù)庫的示例代碼

    Java操作MongoDB數(shù)據(jù)庫的示例代碼

    這篇文章主要介紹了Java操作MongoDB的示例代碼,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Java多線程的臨界資源問題解決方案

    Java多線程的臨界資源問題解決方案

    這篇文章主要介紹了Java多線程的臨界資源問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 關(guān)于Mybatis插入對象時(shí)空值的處理

    關(guān)于Mybatis插入對象時(shí)空值的處理

    這篇文章主要介紹了關(guān)于Mybatis插入對象時(shí)空值的處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • SpringBoot實(shí)現(xiàn)評論回復(fù)功能(數(shù)據(jù)庫設(shè)計(jì))

    SpringBoot實(shí)現(xiàn)評論回復(fù)功能(數(shù)據(jù)庫設(shè)計(jì))

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)評論回復(fù)功能(數(shù)據(jù)庫設(shè)計(jì)),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Mybatis之@ResultMap,@Results,@Result注解的使用

    Mybatis之@ResultMap,@Results,@Result注解的使用

    這篇文章主要介紹了Mybatis之@ResultMap,@Results,@Result注解的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 基于java socket實(shí)現(xiàn) 聊天小程序

    基于java socket實(shí)現(xiàn) 聊天小程序

    這篇文章主要介紹了基于java socket實(shí)現(xiàn) 聊天小程序,代碼分為服務(wù)器和客戶端,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 手把手帶你分析SpringBoot自動裝配完成了Ribbon哪些核心操作

    手把手帶你分析SpringBoot自動裝配完成了Ribbon哪些核心操作

    這篇文章主要介紹了詳解Spring Boot自動裝配Ribbon哪些核心操作的哪些操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Java虛擬機(jī)啟動過程探索

    Java虛擬機(jī)啟動過程探索

    當(dāng)我們在編寫Java應(yīng)用的時(shí)候,很少會注意Java程序是如何被運(yùn)行的,如何被操作系統(tǒng)管理和調(diào)度的,帶著好奇心,探索一下Java虛擬機(jī)啟動過程
    2022-05-05
  • springboot之使用logback日志框架的圖文教程

    springboot之使用logback日志框架的圖文教程

    這篇文章主要介紹了springboot之使用logback日志框架的圖文教程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java中synchronized正確使用方法解析

    Java中synchronized正確使用方法解析

    這篇文章主要介紹了Java中syncronized正確使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09

最新評論