一、背景
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),邵原企業(yè)網(wǎng)站建設(shè),邵原品牌網(wǎng)站建設(shè),網(wǎng)站定制,邵原網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,邵原網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。昨天一位小伙伴面試的時(shí)候被問(wèn)到:Spring AOP中JDK和CGLib動(dòng)態(tài)代理哪個(gè)效率更高?在知識(shí)星球整理了一下,今天特分享出來(lái),供大家參考!
二、基本概念
首先,我們知道Spring AOP的底層實(shí)現(xiàn)有兩種方式:一種是JDK動(dòng)態(tài)代理,另一種是CGLib的方式。
自Java 1.3以后,Java提供了動(dòng)態(tài)代理技術(shù),允許開發(fā)者在運(yùn)行期創(chuàng)建接口的代理實(shí)例,后來(lái)這項(xiàng)技術(shù)被用到了Spring的很多地方。
JDK動(dòng)態(tài)代理主要涉及java.lang.reflect包下邊的兩個(gè)類:Proxy和InvocationHandler。其中,InvocationHandler是一個(gè)接口,可以通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類的代碼,動(dòng)態(tài)地將橫切邏輯和業(yè)務(wù)邏輯編織在一起。
JDK動(dòng)態(tài)代理的話,他有一個(gè)限制,就是它只能為接口創(chuàng)建代理實(shí)例,而對(duì)于沒(méi)有通過(guò)接口定義業(yè)務(wù)方法的類,如何創(chuàng)建動(dòng)態(tài)代理實(shí)例哪?答案就是CGLib。
CGLib采用底層的字節(jié)碼技術(shù),全稱是:Code Generation Library,CGLib可以為一個(gè)類創(chuàng)建一個(gè)子類,在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用并順勢(shì)織入橫切邏輯。
三、JDK 和 CGLib動(dòng)態(tài)代理區(qū)別
1、JDK動(dòng)態(tài)代理具體實(shí)現(xiàn)原理:
通過(guò)實(shí)現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器;
通過(guò)為Proxy類指定ClassLoader對(duì)象和一組interface來(lái)創(chuàng)建動(dòng)態(tài)代理;
通過(guò)反射機(jī)制獲取動(dòng)態(tài)代理類的構(gòu)造函數(shù),其唯一參數(shù)類型就是調(diào)用處理器接口類型;
通過(guò)構(gòu)造函數(shù)創(chuàng)建動(dòng)態(tài)代理類實(shí)例,構(gòu)造時(shí)調(diào)用處理器對(duì)象作為參數(shù)參入;
JDK動(dòng)態(tài)代理是面向接口的代理模式,如果被代理目標(biāo)沒(méi)有接口那么Spring也無(wú)能為力,Spring通過(guò)Java的反射機(jī)制生產(chǎn)被代理接口的新的匿名實(shí)現(xiàn)類,重寫了其中AOP的增強(qiáng)方法。
2、CGLib動(dòng)態(tài)代理:
CGLib是一個(gè)強(qiáng)大、高性能的Code生產(chǎn)類庫(kù),可以實(shí)現(xiàn)運(yùn)行期動(dòng)態(tài)擴(kuò)展java類,Spring在運(yùn)行期間通過(guò) CGlib繼承要被動(dòng)態(tài)代理的類,重寫父類的方法,實(shí)現(xiàn)AOP面向切面編程呢。
3、兩者對(duì)比:
JDK動(dòng)態(tài)代理是面向接口的。
CGLib動(dòng)態(tài)代理是通過(guò)字節(jié)碼底層繼承要代理類來(lái)實(shí)現(xiàn)(如果被代理類被final關(guān)鍵字所修飾,那么抱歉會(huì)失敗)。
4、使用注意:
如果要被代理的對(duì)象是個(gè)實(shí)現(xiàn)類,那么Spring會(huì)使用JDK動(dòng)態(tài)代理來(lái)完成操作(Spirng默認(rèn)采用JDK動(dòng)態(tài)代理實(shí)現(xiàn)機(jī)制);
如果要被代理的對(duì)象不是個(gè)實(shí)現(xiàn)類那么,Spring會(huì)強(qiáng)制使用CGLib來(lái)實(shí)現(xiàn)動(dòng)態(tài)代理。
四、JDK 和 CGLib動(dòng)態(tài)代理性能對(duì)比-教科書上的描述
我們不管是看書還是看文章亦或是我那個(gè)上搜索參考答案,可能很多時(shí)候,都可以找到如下的回答:
關(guān)于兩者之間的性能的話,JDK動(dòng)態(tài)代理所創(chuàng)建的代理對(duì)象,在以前的JDK版本中,性能并不是很高,雖然在高版本中JDK動(dòng)態(tài)代理對(duì)象的性能得到了很大的提升,但是他也并不是適用于所有的場(chǎng)景。主要體現(xiàn)在如下的兩個(gè)指標(biāo)中:
1、CGLib所創(chuàng)建的動(dòng)態(tài)代理對(duì)象在實(shí)際運(yùn)行時(shí)候的性能要比JDK動(dòng)態(tài)代理高不少,有研究表明,大概要高10倍;
2、但是CGLib在創(chuàng)建對(duì)象的時(shí)候所花費(fèi)的時(shí)間卻比JDK動(dòng)態(tài)代理要多很多,有研究表明,大概有8倍的差距;
3、因此,對(duì)于singleton的代理對(duì)象或者具有實(shí)例池的代理,因?yàn)闊o(wú)需頻繁的創(chuàng)建代理對(duì)象,所以比較適合采用CGLib動(dòng)態(tài)代理,反正,則比較適用JDK動(dòng)態(tài)代理。
結(jié)果是不是如上邊1、2、3條描述的那樣哪?下邊我們做一些小實(shí)驗(yàn)分析一下!
五、性能測(cè)試
1、首先有幾個(gè)Java類
2、Target.java
3、TargetImpl.java
4、JdkDynamicProxyTest.java
5、CglibProxyTest.java
6、ProxyPerformanceTest.java
7、測(cè)試結(jié)果
(1)JDK 1.6
(2)JDK 1.7
(3)JDK 1.8
經(jīng)過(guò)多次試驗(yàn),可以看出平均情況下的話,JDK動(dòng)態(tài)代理的運(yùn)行速度已經(jīng)逐漸提高了,在低版本的時(shí)候,運(yùn)行的性能可能不如CGLib,但是在1.8版本中運(yùn)行多次,基本都可以得到一致的測(cè)試結(jié)果,那就是JDK動(dòng)態(tài)代理已經(jīng)比CGLib動(dòng)態(tài)代理快了!
但是JDK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理的適用場(chǎng)景還是不一樣的哈!
六、總結(jié)
最終的測(cè)試結(jié)果大致是這樣的,在1.6和1.7的時(shí)候,JDK動(dòng)態(tài)代理的速度要比CGLib動(dòng)態(tài)代理的速度要慢,但是并沒(méi)有教科書上的10倍差距,在JDK1.8的時(shí)候,JDK動(dòng)態(tài)代理的速度已經(jīng)比CGLib動(dòng)態(tài)代理的速度快很多了,希望小伙伴在遇到這個(gè)問(wèn)題的時(shí)候能夠有的放矢!
Spring AOP中的JDK和CGLib動(dòng)態(tài)代理關(guān)于這個(gè)知識(shí)點(diǎn)很重要,關(guān)于兩者之間性能的對(duì)比經(jīng)過(guò)測(cè)試實(shí)驗(yàn)已經(jīng)有了一個(gè)初步的結(jié)果,以后再有人問(wèn)你Spring AOP,不要簡(jiǎn)單的說(shuō)JDK動(dòng)態(tài)代理和CGLib這兩個(gè)了,是時(shí)候的可以拋出來(lái)對(duì)兩者之間區(qū)別的理解,是有加分的哦!
點(diǎn)擊獲取?附送學(xué)習(xí)進(jìn)階架構(gòu)資料、PDF書籍文檔、面試資料
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
名稱欄目:SpringAOP中JDK和CGLib動(dòng)態(tài)代理哪個(gè)更快?-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://m.newbst.com/article20/cejsjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、企業(yè)網(wǎng)站制作、品牌網(wǎng)站制作、網(wǎng)站排名、網(wǎng)站建設(shè)、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容