溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring AOP中JDK和CGLib動態代理哪個更快?

發布時間:2020-07-14 09:06:01 來源:網絡 閱讀:677 作者:wx5d30212829a35 欄目:編程語言

一、背景

昨天一位小伙伴面試的時候被問到:Spring AOP中JDK和CGLib動態代理哪個效率更高?在知識星球整理了一下,今天特分享出來,供大家參考!

二、基本概念

首先,我們知道Spring AOP的底層實現有兩種方式:一種是JDK動態代理,另一種是CGLib的方式。

自Java 1.3以后,Java提供了動態代理技術,允許開發者在運行期創建接口的代理實例,后來這項技術被用到了Spring的很多地方。

JDK動態代理主要涉及java.lang.reflect包下邊的兩個類:Proxy和InvocationHandler。其中,InvocationHandler是一個接口,可以通過實現該接口定義橫切邏輯,并通過反射機制調用目標類的代碼,動態地將橫切邏輯和業務邏輯編織在一起。

JDK動態代理的話,他有一個限制,就是它只能為接口創建代理實例,而對于沒有通過接口定義業務方法的類,如何創建動態代理實例哪?答案就是CGLib。

CGLib采用底層的字節碼技術,全稱是:Code Generation Library,CGLib可以為一個類創建一個子類,在子類中采用方法攔截的技術攔截所有父類方法的調用并順勢織入橫切邏輯。

三、JDK 和 CGLib動態代理區別

1、JDK動態代理具體實現原理:

  • 通過實現InvocationHandler接口創建自己的調用處理器;

  • 通過為Proxy類指定ClassLoader對象和一組interface來創建動態代理;

  • 通過反射機制獲取動態代理類的構造函數,其唯一參數類型就是調用處理器接口類型;

  • 通過構造函數創建動態代理類實例,構造時調用處理器對象作為參數參入;

JDK動態代理是面向接口的代理模式,如果被代理目標沒有接口那么Spring也無能為力,Spring通過Java的反射機制生產被代理接口的新的匿名實現類,重寫了其中AOP的增強方法。

2、CGLib動態代理:

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

3、兩者對比:

  • JDK動態代理是面向接口的。

  • CGLib動態代理是通過字節碼底層繼承要代理類來實現(如果被代理類被final關鍵字所修飾,那么抱歉會失?。?。

4、使用注意:

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

  • 如果要被代理的對象不是個實現類那么,Spring會強制使用CGLib來實現動態代理。

四、JDK 和 CGLib動態代理性能對比-教科書上的描述

我們不管是看書還是看文章亦或是我那個上搜索參考答案,可能很多時候,都可以找到如下的回答:

關于兩者之間的性能的話,JDK動態代理所創建的代理對象,在以前的JDK版本中,性能并不是很高,雖然在高版本中JDK動態代理對象的性能得到了很大的提升,但是他也并不是適用于所有的場景。主要體現在如下的兩個指標中:

1、CGLib所創建的動態代理對象在實際運行時候的性能要比JDK動態代理高不少,有研究表明,大概要高10倍;

2、但是CGLib在創建對象的時候所花費的時間卻比JDK動態代理要多很多,有研究表明,大概有8倍的差距;

3、因此,對于singleton的代理對象或者具有實例池的代理,因為無需頻繁的創建代理對象,所以比較適合采用CGLib動態代理,反正,則比較適用JDK動態代理。

結果是不是如上邊1、2、3條描述的那樣哪?下邊我們做一些小實驗分析一下!

五、性能測試

1、首先有幾個Java類

Spring AOP中JDK和CGLib動態代理哪個更快?


2、Target.java

Spring AOP中JDK和CGLib動態代理哪個更快?


3、TargetImpl.java

Spring AOP中JDK和CGLib動態代理哪個更快?


4、JdkDynamicProxyTest.java

Spring AOP中JDK和CGLib動態代理哪個更快?


5、CglibProxyTest.java


Spring AOP中JDK和CGLib動態代理哪個更快?



6、ProxyPerformanceTest.java

Spring AOP中JDK和CGLib動態代理哪個更快?


Spring AOP中JDK和CGLib動態代理哪個更快?


7、測試結果

(1)JDK 1.6


Spring AOP中JDK和CGLib動態代理哪個更快?



Spring AOP中JDK和CGLib動態代理哪個更快?



(2)JDK 1.7


Spring AOP中JDK和CGLib動態代理哪個更快?



Spring AOP中JDK和CGLib動態代理哪個更快?



(3)JDK 1.8


Spring AOP中JDK和CGLib動態代理哪個更快?



Spring AOP中JDK和CGLib動態代理哪個更快?



經過多次試驗,可以看出平均情況下的話,JDK動態代理的運行速度已經逐漸提高了,在低版本的時候,運行的性能可能不如CGLib,但是在1.8版本中運行多次,基本都可以得到一致的測試結果,那就是JDK動態代理已經比CGLib動態代理快了!

但是JDK動態代理和CGLib動態代理的適用場景還是不一樣的哈!

六、總結

最終的測試結果大致是這樣的,在1.6和1.7的時候,JDK動態代理的速度要比CGLib動態代理的速度要慢,但是并沒有教科書上的10倍差距,在JDK1.8的時候,JDK動態代理的速度已經比CGLib動態代理的速度快很多了,希望小伙伴在遇到這個問題的時候能夠有的放矢!

Spring AOP中的JDK和CGLib動態代理關于這個知識點很重要,關于兩者之間性能的對比經過測試實驗已經有了一個初步的結果,以后再有人問你Spring AOP,不要簡單的說JDK動態代理和CGLib這兩個了,是時候的可以拋出來對兩者之間區別的理解,是有加分的哦!

點擊獲取?附送學習進階架構資料、PDF書籍文檔、面試資料

Spring AOP中JDK和CGLib動態代理哪個更快?

Spring AOP中JDK和CGLib動態代理哪個更快?


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女