JDK基於接口與CGLib基於繼承
1)、JDK和CGLib的區別
- JDK動態代理只能對實現了接口的類生成代理,而不能針對類
- CGLib是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法(繼承)
2)、Spring在選擇用JDK還是CGLib的依據
- 當Bean實現接口時,Spring就會用JDK的動態代理
- 當Bean沒有實現接口時,Spring使用CGLib來實現
- 可以強制使用CGLib(在Spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>)
3)、JDK和CGLib的性能對比
- 使用CGLib實現動態代理,CGLib底層采用ASM字節碼生成框架,使用字節碼技術生成代理類,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的方法進行代理,因為CGLib原理是動態生成被代理類的子類。
- 在JDK1.6、JDK1.7、JDK1.8逐步對JDK動態代理優化之后,在調用次數較少的情況下,JDK代理效率高於CGLib代理效率,只有當進行大量調用的時候,JDK1.6和JDK1.7比CGLib代理效率低一點,但是到JDK1.8的時候,JDK代理效率高於CGLib代理