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

Spring之AOP兩種代理機制對比分析(JDK和CGLib動態(tài)代理)

 更新時間:2023年05月06日 08:57:35   作者:一個程序猿的夢  
這篇文章主要介紹了Spring之AOP兩種代理機制對比分析(JDK和CGLib動態(tài)代理),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Spring AOP兩種代理機制對比

Spirng的AOP的動態(tài)代理實現(xiàn)機制有兩種,分別是:

JDK動態(tài)代理

具體實現(xiàn)原理:

1、通過實現(xiàn)InvocationHandlet接口創(chuàng)建自己的調(diào)用處理器

2、通過為Proxy類指定ClassLoader對象和一組interface來創(chuàng)建動態(tài)代理

3、通過反射機制獲取動態(tài)代理類的構(gòu)造函數(shù),其唯一參數(shù)類型就是調(diào)用處理器接口類型

4、通過構(gòu)造函數(shù)創(chuàng)建動態(tài)代理類實例,構(gòu)造時調(diào)用處理器對象作為參數(shù)參入

JDK動態(tài)代理是面向接口的代理模式,如果被代理目標(biāo)沒有接口那么Spring也無能為力,

Spring通過java的反射機制生產(chǎn)被代理接口的新的匿名實現(xiàn)類,重寫了其中AOP的增強方法。

CGLib動態(tài)代理

CGLib是一個強大、高性能的Code生產(chǎn)類庫,可以實現(xiàn)運行期動態(tài)擴展java類,Spring在運行期間通過 CGlib繼承要被動態(tài)代理的類,重寫父類的方法,實現(xiàn)AOP面向切面編程呢。

兩者對比:

JDK動態(tài)代理是面向接口,在創(chuàng)建代理實現(xiàn)類時比CGLib要快,創(chuàng)建代理速度快。

CGLib動態(tài)代理是通過字節(jié)碼底層繼承要代理類來實現(xiàn)(如果被代理類被final關(guān)鍵字所修飾,那么抱歉會失敗),在創(chuàng)建代理這一塊沒有JDK動態(tài)代理快,但是運行速度比JDK動態(tài)代理要快。

使用注意:

如果要被代理的對象是個實現(xiàn)類,那么Spring會使用JDK動態(tài)代理來完成操作(Spirng默認(rèn)采用JDK動態(tài)代理實現(xiàn)機制)

如果要被代理的對象不是個實現(xiàn)類那么,Spring會強制使用CGLib來實現(xiàn)動態(tài)代理。

那么如何選擇的使用代理機制了?

通過配置Spring的中<aop:config>標(biāo)簽來顯示的指定使用動態(tài)代理機制 proxy-target-class=true表示使用CGLib代理,如果為false就是默認(rèn)使用JDK動態(tài)代理

SpringAOP兩種代理原理

  

SpringAOP代理

spingAOP代理有兩種:

  • JDK動態(tài)代理:目標(biāo)類必須實現(xiàn)一個接口
  • CGLIB代理:目標(biāo)類必須繼承一個類

JDK動態(tài)代理

JDK為什么一定要目標(biāo)類實現(xiàn)一個接口呢,這其實就得看看JDK動態(tài)代理的原理了,其實JDK動態(tài)代理它是先生成一個代理類然后他也是實現(xiàn)了目標(biāo)類實現(xiàn)的接口里面的方法,只是他還是調(diào)用的是目標(biāo)類的方法。

下面我們來自定義實現(xiàn)一下

//創(chuàng)建一個接口
public interface StudentBiz {
    int add(String name);
    void update(String name);
    void find (String name);
}
//創(chuàng)建一個類實現(xiàn)那個接口
public class StudentBizimpl implements StudentBiz{
    @Override
    public int add(String name) {
        System.out.println("調(diào)用了studentBizimpl中的add"+name);
        return 100;
    }
    @Override
    public void update(String name) {
        System.out.println("調(diào)用了studentBizimpl中的update"+name);
    }
    @Override
    public void find(String name) {
        System.out.println("調(diào)用了studentBizimpl中的find"+name);
    }
}
//jdk動態(tài)代理三大重點
// 1.有目標(biāo)類的引用
// 2.有一個創(chuàng)建代理實例的方法createProxy()里面有Proxy.newProxyInstance()方法來創(chuàng)建代理實例
// 3.有一個回調(diào)方法invoke
public class LogAspect implements InvocationHandler {
    private Object target;//目標(biāo)類的對象
    public LogAspect(Object target){
        this.target=target;
    }
    public Object createProxy(){
        //新建一個代理實例
        //                           第一個參數(shù)是類加載器                        第二個是得獲取到目標(biāo)類實現(xiàn)的接口       第三個是代理類對象
        return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass().getInterfaces(),this);
    }
    @Override//回調(diào)方法   當(dāng)jvm調(diào)用代理對象的被代理的方法時,會由jvm自動調(diào)用這個invoke
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理類對象:"+proxy.getClass());
        System.out.println("目標(biāo)的方法:"+method);
        System.out.println("方法的參數(shù):"+args);
        log();//這里就可以加增強    具體哪些方法加得看切入點表達式來判斷
        Object o=method.invoke(this.target,args);//激活目標(biāo)類方法
        return o;
    }
    private void log(){
        System.out.println("前置增強");
    }
}

下面我們再來做一個測試類:

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        StudentBiz sbm=new StudentBizimpl();
        LogAspect la=new LogAspect(sbm);//放目標(biāo)類對象
        Object o=la.createProxy();//創(chuàng)建一個代理類
        if (o instanceof StudentBiz){
            StudentBiz sb=(StudentBiz)o;
            sb.add("張三");//這里就會自動回調(diào)invoke方法
        }
    }
}

得到以下結(jié)果:

CGLIB代理

CGLib是一個強大、高性能的Code生產(chǎn)類庫,可以實現(xiàn)運行期動態(tài)擴展java類,Spring在運行期間通過 CGlib繼承要被動態(tài)代理的類,重寫父類的方法,實現(xiàn)AOP面向切面編程呢。

CGLIB代理其實也就是生成一個代理對象他也繼承了目標(biāo)類的父類中的方法,再通過回調(diào)自身引用目標(biāo)類的方法完成代理.

下面來簡單地自定義實現(xiàn)一下

//做一個cglib代理類
public class LogAspectcglib implements MethodInterceptor {
    private Object target;
    public LogAspectcglib(Object target){
        this.target=target;
    }
    public Object createProxy(){
        Enhancer enhancer=new Enhancer();//用于生成代理對象
        enhancer.setSuperclass(this.target.getClass());//設(shè)置父類
        enhancer.setCallback(this);//設(shè)置回調(diào)用對象為本身
        return enhancer.create();//創(chuàng)建代理對象
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理類對象"+o.getClass());
        System.out.println("目標(biāo)類的方法"+method);
        System.out.println("目標(biāo)方法參數(shù)"+objects);
        System.out.println("要代理的方法"+methodProxy);
       Object returnvalue= method.invoke(this.target,objects);
        return returnvalue;
    }
}

測試類:

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        StudentBizimpl sbm=new StudentBizimpl();
        LogAspectcglib lac=new LogAspectcglib(sbm);
        Object o=lac.createProxy();
        if (o instanceof StudentBizimpl){
            StudentBizimpl sb=(StudentBizimpl) o;
            sb.add("張三");
        }
    }
}

得到結(jié)果:

兩者對比

  • JDK動態(tài)代理是面向接口,在創(chuàng)建代理實現(xiàn)類時比CGLib要快,創(chuàng)建代理速度快。
  • CGLib動態(tài)代理是通過字節(jié)碼底層繼承要代理類來實現(xiàn)(如果被代理類被final關(guān)鍵字所修飾,那么抱歉會失?。?,在創(chuàng)建代理這一塊沒有JDK動態(tài)代理快,但是運行速度比JDK動態(tài)代理要快。

使用注意

如果要被代理的對象是個實現(xiàn)類,那么Spring會使用JDK動態(tài)代理來完成操作(Spirng默認(rèn)采用JDK動態(tài)代理實現(xiàn)機制)

如果要被代理的對象不是個實現(xiàn)類那么,Spring會強制使用CGLib來實現(xiàn)動態(tài)代理。

如果要強制使用CGLIB代理則需在xml中配置如下:

<aop:aspectj-autoproxy proxy-target-class="true"/>

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談MyBatisPlus中LocalDateTime引發(fā)的一些問題和解決辦法

    淺談MyBatisPlus中LocalDateTime引發(fā)的一些問題和解決辦法

    MyBatisPlus進行數(shù)據(jù)庫操作時,我們經(jīng)常會遇到處理日期時間類型的需求,本文主要介紹了淺談MyBatisPlus中LocalDateTime引發(fā)的一些問題和解決辦法,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟

    Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟

    本文主要介紹了Eclipse開發(fā)JavaWeb項目配置Tomcat的方法步驟,首先介紹eclipse開發(fā)JavaWeb項目需要配置的相關(guān)環(huán)境,使用tomcat軟件在本地搭建服務(wù)器,然后再在eclipse環(huán)境下配置tomcat,感興趣的可以了解一下
    2021-08-08
  • Java利用Strategy模式實現(xiàn)堆排序

    Java利用Strategy模式實現(xiàn)堆排序

    策略設(shè)計模式(Strategy):可以整體的替換一個算法的實現(xiàn)部分,能夠整體的替換算法,能讓我們輕松地用不同方法解決同一個問題。本文將利用Strategy模式實現(xiàn)堆排序,感興趣的可以學(xué)習(xí)一下
    2022-09-09
  • Spring中的aware接口詳情

    Spring中的aware接口詳情

    這篇文章主要介紹了Spring中的aware接口詳情,Spring中有很多繼承于aware中的接口,這些接口到底是做什么用到的,下面我們就一起來看看吧,文章詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • SpringBoot整合ELK使用教程

    SpringBoot整合ELK使用教程

    對于一個運行中的應(yīng)用來說,線上排查問題是一件很頭疼的問題,不管是springboot單應(yīng)用,還是springcloud微服務(wù)應(yīng)用,一旦在生產(chǎn)環(huán)境出了問題,大多數(shù)人第一反應(yīng)就是趕緊去看日志查問題,本文給大家介紹了SpringBoot整合ELK使用教程,需要的朋友可以參考下
    2024-11-11
  • SpringBoot實現(xiàn)類似鉤子函數(shù)的方法

    SpringBoot實現(xiàn)類似鉤子函數(shù)的方法

    這篇文章主要給大家介紹了關(guān)于SpringBoot實現(xiàn)類似鉤子函數(shù)的方法,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-04-04
  • SpringBoot后端接收數(shù)組對象的實現(xiàn)

    SpringBoot后端接收數(shù)組對象的實現(xiàn)

    這篇文章主要介紹了SpringBoot后端接收數(shù)組對象的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringBoot實現(xiàn)啟動項目后立即執(zhí)行的方法總結(jié)

    SpringBoot實現(xiàn)啟動項目后立即執(zhí)行的方法總結(jié)

    在項目開發(fā)中某些場景必須要用到啟動項目后立即執(zhí)行方式的功能,所以這篇文章就來和大家聊聊實現(xiàn)立即執(zhí)行的幾種方法,希望對大家有所幫助
    2023-05-05
  • Java實現(xiàn)爬取往期所有雙色球開獎結(jié)果功能示例

    Java實現(xiàn)爬取往期所有雙色球開獎結(jié)果功能示例

    這篇文章主要介紹了Java實現(xiàn)爬取往期所有雙色球開獎結(jié)果功能,涉及Java網(wǎng)頁抓取、正則替換、文件讀寫等相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • java線程之使用Runnable接口創(chuàng)建線程的方法

    java線程之使用Runnable接口創(chuàng)建線程的方法

    本篇文章介紹了,java中使用Runnable接口創(chuàng)建線程的方法。需要的朋友參考下
    2013-05-05

最新評論

英超| 西畴县| 丹凤县| 夏河县| 达拉特旗| 永仁县| 门源| 阜新市| 凤翔县| 呼伦贝尔市| 巴彦县| 诏安县| 华安县| 焉耆| 泰顺县| 屯门区| 东方市| 东光县| 崇州市| 金坛市| 宣威市| 上饶县| 大邑县| 偏关县| 县级市| 乌兰浩特市| 漳平市| 渝北区| 托里县| 南开区| 泰兴市| 锦州市| 射阳县| 盘锦市| 唐海县| 通化市| 法库县| 石嘴山市| 太仆寺旗| 江华| 长海县|