最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的CGLIB動(dòng)態(tài)代理深入解析

 更新時(shí)間:2023年11月27日 09:53:54   作者:一碼評川  
這篇文章主要介紹了Java的CGLIB動(dòng)態(tài)代理深入解析,CGLIB是強(qiáng)大的、高性能的代碼生成庫,被廣泛應(yīng)用于AOP框架,它底層使用ASM來操作字節(jié)碼生成新的類,為對象引入間接級(jí)別,以控制對象的訪問,需要的朋友可以參考下

一、介紹

CGLIB是強(qiáng)大的、高性能的代碼生成庫,被廣泛應(yīng)用于AOP框架,它底層使用ASM來操作字節(jié)碼生成新的類,為對象引入間接級(jí)別,以控制對象的訪問。

CGLIB相比于JDK動(dòng)態(tài)代理更加強(qiáng)大,JDK動(dòng)態(tài)代理只能對接口進(jìn)行代理,而CGLIB既可以代理普通類,也能夠代理接口。

優(yōu)點(diǎn): 通過FastClass機(jī)制調(diào)用方法,比JDK動(dòng)態(tài)代理的反射機(jī)制效率高;被代理類無需實(shí)現(xiàn)接口

缺點(diǎn): 運(yùn)行期生成字節(jié)碼,通過ASM寫Class字節(jié)碼,效率低;不能對final類及final方法進(jìn)行代理

二、工作原理

g

CGLIB 通過動(dòng)態(tài)生成一個(gè)需要被代理類的子類(即被代理類作為父類),該子類重寫被代理類的所有不是 final 修飾的方法,并在子類中采用方法攔截的技術(shù)攔截父類所有的方法調(diào)用,進(jìn)而織入橫切邏輯。此外,因?yàn)?CGLIB 采用整型變量建立了方法索引,這比使用 JDK 動(dòng)態(tài)代理更快(使用 Java 反射技術(shù)創(chuàng)建代理類的實(shí)例)。

2.1步驟說明

生成代理對象 創(chuàng)建要被代理的類或接口–MyFly

public class MyFly implements Fly {
    @Override
    public void doFly() {
        System.out.println("wo的");
    }
}

實(shí)現(xiàn)MethodInterceptor并實(shí)現(xiàn)intercept方法 --CglibProxy

class CglibProxy implements MethodInterceptor {
    /**
     * @param o:           代理對象
     * @param method:      被代理方法
     * @param params:      方法入?yún)?
     * @param methodProxy: CGLIB方法
     **/
    @Override
    public Object intercept(Object o, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
        System.out.println("【增強(qiáng)方法】代理對象正在執(zhí)行的方法:" + method.getName());
        Object result = methodProxy.invokeSuper(o, params);
        return result;
    }
}

創(chuàng)建Enhancer(設(shè)置要被代理的類和調(diào)用方法時(shí)觸發(fā)的攔截器)

 public static Object creatCglibProxyObj(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        // 為加強(qiáng)器指定要代理的業(yè)務(wù)類(即為下面生成的代理類指定父類)
        enhancer.setSuperclass(clazz);
        // 設(shè)置回調(diào):對于代理類上所有方法的調(diào)用,都會(huì)調(diào)用CallBack,而Callback則需要實(shí)現(xiàn)intercept()方法
        enhancer.setCallback(new CglibProxy());
        return enhancer.create();
    }

執(zhí)行程序

public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");
        Fly fly = (Fly) CglibProxyFactory.creatCglibProxyObj(MyFly.class);
        fly.doFly();
    }

結(jié)果:

在這里插入圖片描述

2.2 代理對象分析

通過設(shè)置屬性來輸出生成的代理對象

System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");

在這里插入圖片描述

通過IDEA打開class文件

2.2.1表頭分析

在這里插入圖片描述

結(jié)論: 生成的代理對象繼承了我們需要被代理的對象同時(shí)實(shí)現(xiàn)了Factory這里是通過繼承的方式來代理的,所以他即可以代理類也可以代理接口因?yàn)槭抢^承了被代理類,所以在java中子類是無法重寫父類final方法的,這也就解釋了為什么CGLIB無法代理final修飾的方法了

2.2.2 stataic 靜態(tài)代碼塊

在這里插入圖片描述

結(jié)論: 這里面創(chuàng)建了一些后續(xù)要試用的變量引用

2.2.3 重寫父類方法

在這里插入圖片描述

結(jié)論: 重寫的方法被final,防止后面被修改這里的var10000就是我們在創(chuàng)建代理時(shí)傳入的CglibProxy這里也就解釋了CGLIB是如何動(dòng)態(tài)增強(qiáng)方法的基本邏輯(在每次調(diào)用方法時(shí)都會(huì)先去調(diào)用MethodInterceptor的實(shí)現(xiàn)類中的intercept方法,然后我們只需要在intercept方法中實(shí)現(xiàn)要加強(qiáng)的代碼即可)

2.3 代理方法調(diào)用過程分析

調(diào)用代理方法

在這里插入圖片描述

結(jié)論: 創(chuàng)建代理對象fly通過調(diào)用代理對象fly.doFly()方法

在這里插入圖片描述

3. 調(diào)用MethodInterceptor的intercept方法,這里就是調(diào)用我們的CglibProxy

在這里插入圖片描述

4. 調(diào)用methodProxy.invokeSuper(o, params);這里就是要調(diào)用被代理類的原始方法

在這里插入圖片描述

通過init()來初始化生成代理類和被代理類的FastClass

在這里插入圖片描述

helper:

在這里插入圖片描述

生成的FastClass文件

在這里插入圖片描述

生成的FastClass文件的invoke方法

在這里插入圖片描述

init完成后這里會(huì)繼續(xù)調(diào)用fci.f2.invoke(fci.i2, obj, args); 這里的fci.f2就是剛剛生成的代理對象FastCalss對象

在這里插入圖片描述

這里程序會(huì)傳入17,調(diào)用代理類的CGLIB$doFly$0()方法;(大家可以debug看,每次生成的文件位置會(huì)不一樣)

在這里插入圖片描述

調(diào)用代理類的CGLIB$doFly$0() 到這里基本可以知道它是如何幫助我們調(diào)用被代理類的方法了這里的super指的就是MyFly,因?yàn)镃GLIB生成的代理類繼承了我們要被代理的類

在這里插入圖片描述

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

相關(guān)文章

  • 關(guān)于BufferedReader的讀取效率問題

    關(guān)于BufferedReader的讀取效率問題

    這篇文章主要介紹了關(guān)于BufferedReader的讀取效率問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • JAVA基礎(chǔ)快速從入門到精通

    JAVA基礎(chǔ)快速從入門到精通

    Java是一門面向?qū)ο蟮木幊陶Z言,不僅吸收了C++語言的各種優(yōu)點(diǎn),還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強(qiáng)大和簡單易用兩個(gè)特征
    2022-03-03
  • Java遞歸遍歷文件目錄代碼實(shí)例

    Java遞歸遍歷文件目錄代碼實(shí)例

    這篇文章主要介紹了Java遞歸遍歷文件目錄代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 如何修改logback.xml配置文件在resource以外的位置

    如何修改logback.xml配置文件在resource以外的位置

    這篇文章主要介紹了如何修改logback.xml配置文件在resource以外的位置,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • JavaCV 拉流存儲(chǔ)到本地示例解析

    JavaCV 拉流存儲(chǔ)到本地示例解析

    這篇文章主要介紹了JavaCV 拉流存儲(chǔ)到本地示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • java?ArrayList的深拷貝與淺拷貝問題

    java?ArrayList的深拷貝與淺拷貝問題

    這篇文章主要介紹了java?ArrayList的深拷貝與淺拷貝問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 淺談Timer和TimerTask與線程的關(guān)系

    淺談Timer和TimerTask與線程的關(guān)系

    下面小編就為大家?guī)硪黄獪\談Timer和TimerTask與線程的關(guān)系。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • 從Java到Kotlin語法平滑遷移實(shí)踐指南(含詳細(xì)代碼)

    從Java到Kotlin語法平滑遷移實(shí)踐指南(含詳細(xì)代碼)

    Kotlin作為一門現(xiàn)代編程語言,憑借其簡潔的語法、強(qiáng)大的功能和與Java的無縫互操作性,已成為Android開發(fā)的首選語言,這篇文章主要介紹了從Java到Kotlin語法平滑遷移的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-05-05
  • Java中@JSONField注解的使用詳解

    Java中@JSONField注解的使用詳解

    這篇文章主要介紹了Java中@JSONField注解的使用,@JSONField是阿里巴巴開源的JSON處理庫FastJSON提供的一個(gè)注解,用于在Java對象和JSON數(shù)據(jù)之間進(jìn)行序列化和反序列化時(shí),對字段的行為進(jìn)行更精細(xì)的控制,需要的朋友可以參考下
    2025-05-05
  • java中isEmpty和isBlank的區(qū)別小結(jié)

    java中isEmpty和isBlank的區(qū)別小結(jié)

    Java中的isEmpty和isBlank都是用來判斷字符串是否為空的方法,但在不同的情況下有所區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09

最新評論

上林县| 工布江达县| 红河县| 台山市| 腾冲县| 霸州市| 荔波县| 灵武市| 永川市| 贺州市| 乐山市| 赤壁市| 上栗县| 内乡县| 星子县| 江源县| 高唐县| 增城市| 孙吴县| 芜湖市| 凉城县| 鄄城县| 宜丰县| 汤原县| 乌拉特前旗| 青神县| 青海省| 道孚县| 凤台县| 保德县| 崇文区| 浦东新区| 库伦旗| 康平县| 城固县| 襄樊市| 辽源市| 民县| 商南县| 张家港市| 揭阳市|