jdk的動態代理
1. java動態代理和cglib動態代理的區別
1、Jdk動態代理實例:復JDK動態代制理只能代理實現了介面的類,其他普通類不能實現。代理類會在newProxyInstance方法中生成
2、cglib動態代理:cglib是針對類實現代理的,為代理的類生成一個子類,覆蓋方法實現增強,因為採用的是繼承所以不能代理final修飾的類。需要cglib和asm兩個jar包
2. jdk 動態代理與spring 動態代理區別
spring有兩種動態代理方式,一種就是jdk動態代理,還有就是cglib動態代理,jdk動態代理只能代理介面,cglib可以是類。jdk代理生成速度比cglib快,性能沒有cglib好
3. jdk動態代理與cglib動態代理有什麼區別
1.JDK動態代理
此時代理對象和目標對象實現了相同的介面,目標對象作為代理對象的一個屬性,具體介面實現中,可以在調用目標對象相應方法前後加上其他業務處理邏輯。
代理模式在實際使用時需要指定具體的目標對象,如果為每個類都添加一個代理類的話,會導致類很多,同時如果不知道具體類的話,怎樣實現代理模式呢?這就引出動態代理。
JDK動態代理只能針對實現了介面的類生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的所有方法,所以該類或方法不能聲明稱final的。
如果目標對象沒有實現介面,則默認會採用CGLIB代理;
如果目標對象實現了介面,可以強制使用CGLIB實現代理(添加CGLIB庫,並在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。
AOP包括切面(aspect)、通知(advice)、連接點(joinpoint),實現方式就是通過對目標對象的代理在連接點前後加入通知,完成統一的切面操作。
4. 靜態代理,JDK動態代理和CGLib動態代理之前的區別
1、靜態代理:靜態代理中的代理類,需要我們自己寫
JDK動態代理類實現了InvocationHandler介面。在重寫的invoke方法中可以看出,動態代理的基礎是反射(method.invoke(對象,參數)),還好反射看的比較多,到現在還記得。在這里需要提到的是Proxy.newProxyInstance(),這個方法。字面上的意思是 新建一個代理類的實例,這一點就和靜態代理不同了。裡面的參數有三個 類載入器、所有的介面,得到InvocationHandler介面的子類實例。這就是JDK動態代理,該代理有以下幾種特點:
1、Interface:對於JDK Proxy,業務類是需要一個Interface的,這是一個缺陷;
2、Proxy:Proxy類是動態產生的,這個類在調用Proxy.newProxyInstance()方法之後,產生一個Proxy類的實力。實際上,這個Proxy類也是存在的,不僅僅是類的實例,這個Proxy類可以保存在硬碟上;
3、Method:對於業務委託類的每個方法,現在Proxy類裡面都不用靜態顯示出來
4、InvocationHandler:這個類在業務委託類執行時,會先調用invoke方法。invoke方法在執行想要的代理操作,可以實現對業務方法的再包裝。
以上就是JDK動態代理
3、CGLib動態代理:上面的JDK Proxy只能代理實現了介面的類,而不能實現介面的類就不能實現JDK代理。這時候就需要CGLib動態代理類
這里需要注意的是實現MethodIntercetor介面,必須導入cglib-nodep-2.1_3.jar這個包。CGLib是針對類來實現代理的,他的原理是對指定的目標生成一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理。
5. spring對AOP的支持 JDK動態代理和CGLIB的區別
Aspect默認情況下不來用實現介面,但對源於目標對象(UserManagerImpl.java),在默認情況下必須實現介面
如果沒有實現介面必須引入CGLIB庫
我們可以通過Advice中添加一個JoinPoint參數,這個值會由spring自動傳入,從JoinPoint中可以取得
參數值、方法名等等
1、如果目標對象實現了介面,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了介面,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換
如何強制使用CGLIB實現AOP?
* 添加CGLIB庫,SPRING_HOME/cglib/*.jar
* 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK動態代理和CGLIB位元組碼生成的區別?
* JDK動態代理只能對實現了介面的類生成代理,而不能針對類
* CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法
因為是繼承,所以該類或方法最好不要聲明成final
6. JDK動態代理和CGLIB代理的區別
區別:
java動態代理是利用反射機制生成一個實現代理介面的匿名類,在調用具體方法回前調用InvokeHandler來處理。而cglib動態答代理是利用asm開源包,對代理對象類的class文件載入進來,通過修改其位元組碼生成子類來處理。
1、如果目標對象實現了介面,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了介面,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換
7. JDK的動態代理為什麼必須要使用介面與使用C
代理模式的定義:為其他對象提供一種代理以控制對這個對象的訪問。在內某些情況下,一個對象不適合或容者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。
介面是一種規范,定義了一組相似的行為。
通俗一些就是,當調用代理類的方法時與調用被代理類的方法時在寫法上是沒有任何區別的,只有介面才能保證這種一致性。
8. 如何獲得jdk動態代理proxy的原始類
可以在通知中(如@Before等)通過JoinPoint獲取class對象(proxy):point.getTarget().getClass();
如果proxy實現介面版,再通過class.getInterfaces()即可獲取原始類;
如果proxy是使用繼承權父類的方式,通過class.getSuperClass()即可獲取原始類。
9. JDK動態代理生成的代理類在哪兒
spring代理類有用jdk的動態代理,也有用cglib包,cglib底層依賴asm包,asm同樣在hibernate中也被使用,使用asm增強位元組碼,自動生成代理類,方法跟目標類基本一樣
10. cglib動態代理和jdk動態代理的區別與應用
jdk動態代理:需要有頂層介面才能使用,但是在只有頂層介面的時候也可以使用,常版見是權mybatis的mapper文件是代理.
cglib動態代理:可以直接代理類,使用位元組碼技術,不能對 final類進行繼承。使用了動態生成位元組碼技術。