Spring AOP

  • JDK的動(dòng)態(tài)代理:只能用于實(shí)現(xiàn)了接口的類(lèi)產(chǎn)生代理。
  • Cglib代理:針對(duì)沒(méi)有實(shí)現(xiàn)接口的類(lèi)產(chǎn)生代理,應(yīng)用的是底層的字節(jié)碼增強(qiáng)技術(shù),生成當(dāng)前類(lèi)的子類(lèi)對(duì)象。

JDK動(dòng)態(tài)代理:

JDK的動(dòng)態(tài)代理主要涉及到j(luò)ava.lang. reflect包中的兩個(gè)類(lèi):Proxy和InvocationHandler
其中 InvocationHandler是一個(gè)接口,可以通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,在并通過(guò)反射機(jī)制調(diào)用目標(biāo)類(lèi)的代碼,動(dòng)態(tài)將橫切邏輯和業(yè)務(wù)邏輯編織在一起。
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
JDK的動(dòng)態(tài)代理必須具備四個(gè)條件: 目標(biāo)接口,目標(biāo)類(lèi),攔截器(處理器),代理類(lèi)
1、因?yàn)槔肑DKProxy生成的代理類(lèi)實(shí)現(xiàn)了接口,所以目標(biāo)類(lèi)中所有的方法在代理類(lèi)中都有。
2、生成的代理類(lèi)的所有的方法都攔截了目標(biāo)類(lèi)的所有的方法。而攔截器(處理器)中invoke方法的內(nèi)容正好就是代理類(lèi)的各個(gè)方法的組成體。
3、利用JDKProxy方式必須有接口的存在。
4、invoke方法中的三個(gè)參數(shù)可以訪問(wèn)目標(biāo)類(lèi)的被調(diào)用方法的API、被調(diào)用方法的參數(shù)、被調(diào)用方法的返回類(lèi)型。

CGLib

CGLib采用非常底層的字節(jié)碼技術(shù),可以為一個(gè)類(lèi)創(chuàng)建子類(lèi),并在子類(lèi)中采用方法攔截的技術(shù)攔截所有父類(lèi)方法的調(diào)用,并在攔截方法相應(yīng)地方織入橫切邏輯。
1、 CGlib是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類(lèi)庫(kù)。它可以在運(yùn)行期擴(kuò)展Java類(lèi)與實(shí)現(xiàn)Java接口。
2、 用CGlib生成代理類(lèi)是目標(biāo)類(lèi)的子類(lèi)。
3、 用CGlib生成代理類(lèi)不需要接口。
4、 用CGLib生成的代理類(lèi)重寫(xiě)了父類(lèi)的各個(gè)方法。
5、 攔截器中的intercept方法內(nèi)容正好就是代理類(lèi)中的方法體。
CGLib所創(chuàng)建的動(dòng)態(tài)代理對(duì)象的性能依舊比JDK的所創(chuàng)建的代理對(duì)象的性能高不少(大概10倍)。
而CGLib在創(chuàng)建代理對(duì)象時(shí)性能卻比JDK動(dòng)態(tài)代理慢很多(大概8倍),
所以對(duì)于singleton的代理對(duì)象或者具有實(shí)例池的代理,因?yàn)椴恍枰l繁創(chuàng)建代理對(duì)象,所以比較適合用CGLib動(dòng)態(tài)代理技術(shù),反之適合用JDK動(dòng)態(tài)代理技術(shù)。此外,由于CGLib采用生成子類(lèi)的技術(shù)創(chuàng)建代理對(duì)象,所以不能對(duì)目標(biāo)類(lèi)中的final方法進(jìn)行代理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容