Cglib和jdk動態代理的區別

Cglib和jdk動態代理的區別?
a) Jdk動態代理:利用攔截器(必須實現InvocationHandler)加上反射機制生成一個代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理
b) Cglib動態代理:利用ASM框架,對代理對象類生成的class文件加載進來,通過修改其字節碼生成子類來處理
c) 什麼時候用cglib什麼時候用jdk動態代理
i. 目標對象生成了接口 默認用JDK動態代理
ii. 如果目標對象使用了接口,可以強制使用cglib
iii. 如果目標對象沒有實現接口,必須採用cglib庫,Spring會自動在JDK動態代理和cglib之間轉換
d) JDK動態代理和cglib字節碼生成的區別?
i. JDK動態代理只能對實現了接口的類生成代理,而不能針對類
ii. Cglib是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法,並覆蓋其中方法的增強,但是因爲採用的是繼承,所以該類或方法最好不要生成final,對於final類或方法,是無法繼承的
e) Cglib比JDK快
i. cglib底層是ASM字節碼生成框架,但是字節碼技術生成代理類,在JDL1.6之前比使用java反射的效率要高
ii. 在jdk6之後逐步對JDK動態代理進行了優化,在調用次數比較少時效率高於cglib代理效率
iii. 只有在大量調用的時候cglib的效率高,但是在1.8的時候JDK的效率已高於cglib
iv. Cglib不能對聲明final的方法進行代理,因爲cglib是動態生成代理對象,final關鍵字修飾的類不可變只能被引用不能被修改
f) Spring如何選擇是用JDK還是cglib
i. 當bean實現接口時,會用JDK代理模式
ii. 當bean沒有實現接口,用cglib實現
iii. 可以強制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxyt-target-class=”true”/>)
Cglib是什麼?
一. Cglib原理

  1. 動態生成一個要代理的子類,子類重寫要代理的類的所有不是final的方法。在子類中採用方法攔截技術攔截所有的父類方法的調用,順勢織入橫切邏輯,它比Java反射的jdk動態代理要快
    Cglib是一個強大的、高性能的代碼生成包,它被廣泛應用在許多AOP框架中,爲他們提供方法的攔截
    在這裏插入圖片描述
     最底層的是字節碼Bytecode,字節碼是java爲了保證依次運行,可以跨平臺使用的一種虛擬指令格式
     在字節碼文件之上的是ASM,只是一種直接操作字節碼的框架,應用ASM需要對Java字節碼、class結構比較熟悉
     位於ASM上面的是Cglib,groovy、beanshell,後來那個種並不是Java體系中的內容是腳本語言,他們通過ASM框架生成字節碼變相執行Java代碼,在JVM中程序執行不一定非要寫java代碼,只要能生成java字節碼,jvm並不關係字節碼的來源
     位於cglib、groovy、beanshell之上的就是hibernate和spring AOP
     最上面的是applications,既具體應用,一般是一個web項目或者本地跑一個程序、
    使用cglib代碼對類做代理?
    使用cglib定義不同的攔截策略?
    構造函數不攔截方法
    用MethodInterceptor和Enhancer實現一個動態代理
     Jdk中的動態代理
     JDK中的動態代理是通過反射類Proxy以及InvocationHandler回調接口實現的,但是JDK中所有要進行動態代理的類必須要實現一個接口,也就是說只能對該類所實現接口中定義的方法進行代理,這在實際編程中有一定的侷限性,而且使用反射的效率也不高
     Cglib實現
    使用cglib是實現動態代理,不受代理類必須實現接口的限制,因爲cglib底層是用ASM框架,使用字節碼技術生成代理類,你使用Java反射的效率要高,cglib不能對聲明final的方法進行代理,因爲cglib原理是動態生成被代理類的子類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章