Jdk代理和CGLIB代理的區別

熊貓IT學院發表於2020-12-09

1.原理區別

java動態代理是利用反射機制生成一個實現代理介面的匿名類,在呼叫具體方法前呼叫InvokeHandler來處理。核心是實現InvocationHandler介面,使用invoke()方法進行面向切面的處理,呼叫相應的通知。

而cglib動態代理是利用asm開源包,對代理物件類的class檔案載入進來,通過修改其位元組碼生成子類來處理。核心是實現MethodInterceptor介面,使用intercept()方法進行面向切面的處理,呼叫相應的通知。

  1. 如果目標物件實現了介面,預設情況下會採用JDK的動態代理實現AOP

  2. 如果目標物件實現了介面,可以強制使用CGLIB實現AOP

  3. 如果目標物件沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

可以強制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>
springboot專案配置: spring.aop.proxy-target-class=false

2.CGlib比JDK快?

1、CGLib底層採用ASM位元組碼生成框架,使用位元組碼技術生成代理類,在jdk6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能對宣告為final的方法進行代理,因為CGLib原理是動態生成被代理類的子類。

2、在jdk6、jdk7、jdk8逐步對JDK動態代理優化之後,在呼叫次數較少的情況下,JDK代理效率高於CGLIB代理效率,只有當進行大量呼叫的時候,jdk6和jdk7比CGLIB代理效率低一點,但是到jdk8的時候,jdk代理效率高於CGLIB代理。

3、在對JDK動態代理與CGlib動態代理的程式碼實驗中看,1W次執行下,JDK7及8的動態代理效能比CGlib要好20%左右。

3.各自侷限:

1、JDK的動態代理機制只能代理實現了介面的類,而不能實現介面的類就不能實現JDK的動態代理。

2、cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理。

4. 總結

在這裡插入圖片描述

相關文章