JDK和CGLIB生成動態代理類的區別
關於動態代理和靜態代理
當一個物件(客戶端)不能或者不想直接引用另一個物件(目標物件),這時可以應用代理模式在這兩者之間構建一個橋樑--代理物件。
按照代理物件的建立時期不同,可以分為兩種:
靜態代理:事先寫好代理物件類,在程式釋出前就已經存在了;
動態代理:應用程式釋出後,通過動態建立代理物件。
靜態代理其實就是一個典型的代理模式實現,在代理類中包裝一個被代理物件,然後影響被代理物件的行為,比較簡單,程式碼就不放了。
其中動態代理又可分為:JDK動態代理和CGLIB代理。
1.JDK動態代理
此時代理物件和目標物件實現了相同的介面,目標物件作為代理物件的一個屬性,具體介面實現中,可以在呼叫目標物件相應方法前後加上其他業務處理邏輯。
代理模式在實際使用時需要指定具體的目標物件,如果為每個類都新增一個代理類的話,會導致類很多,同時如果不知道具體類的話,怎樣實現代理模式呢?這就引出動態代理。
JDK動態代理只能針對實現了介面的類生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是針對類實現代理,
主要是對指定的類生成一個子類,覆蓋其中的所有方法,所以該類或方法不能宣告稱final的。
JDK動態代理和CGLIB代理生成的區別
JDK動態代理只能對實現了介面的類生成代理,而不能針對類 。
CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法 。
因為是繼承,所以該類或方法最好不要宣告成final ,final可以阻止繼承和多型。
PS:final 所修飾的資料具有“終態”的特徵,表示“最終的”意思:
- final 修飾的類不能被繼承。
- final 修飾的方法不能被子類重寫。
- final 修飾的變數(成員變數或區域性變數)即成為常量,只能賦值一次。
- final 修飾的成員變數必須在宣告的同時賦值,如果在宣告的時候沒有賦值,那麼只有 一次賦值的機會,而且只能在構造方法中顯式賦值,然後才能使用。
- final 修飾的區域性變數可以只宣告不賦值,然後再進行一次性的賦值。
參考程式碼
CGLIB:
1 2 3 4 5 6 7 8 |
public Object
createProxyObject(Object obj) { this .targetObject
= obj;
Enhancer
enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback( this );
Object
proxyObj = enhancer.create();
return proxyObj; //
返回代理物件,返回的物件其實就是一個封裝了“實現類”的代理類,是實現類的例項。
}
|
JDK:
1 2 3 4 5 |
public Object
newProxy(Object targetObject) { //
將目標物件傳入進行代理
this .targetObject
= targetObject; <br> //注意這個方法的引數,後面是類實現的介面
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this ); //
返回代理物件
}
|
在程式碼中可以看到,在生成代理類時,傳遞的是實現類所實現的介面 targetObject.getClass().getInterfaces(),所以JDK只能對於介面進行做代理。如果換成類的話,則會拋java.lang.ClassCastException異常。
在Spring的原始碼中,可以看到很多生成代理類的程式碼。
動態代理的應用
AOP(Aspect-OrientedProgramming,面向切面程式設計),AOP包括切面(aspect)、通知(advice)、連線點(joinpoint),實現方式就是通過對目標物件的代理在連線點前後加入通知,完成統一的切面操作。
實現AOP的技術,主要分為兩大類:
一是採用動態代理技術,利用擷取訊息的方式,對該訊息進行裝飾,以取代原有物件行為的執行;
二是採用靜態織入的方式,引入特定的語法建立“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的程式碼。
Spring提供了兩種方式來生成代理物件: JDKProxy和Cglib,具體使用哪種方式生成由AopProxyFactory根據AdvisedSupport物件的配置來決定。
預設的策略是如果目標類是介面,則使用JDK動態代理技術,如果目標物件沒有實現介面,則預設會採用CGLIB代理。
如果目標物件實現了介面,可以強制使用CGLIB實現代理(新增CGLIB庫,並在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)
相關推薦
JDK和CGLIB生成動態代理類的區別
關於動態代理和靜態代理 當一個物件(客戶端)不能或者不想直接引用另一個物件(目標物件),這時可以應用代理模式在這兩者之間構建一個橋樑--代理物件。 按照代理物件的建立時期不同,可以分為兩種: 靜態代理:事先寫好代理物件類,在程式釋出前就已經存在了; 動態代理:應
Spring中AOP實現的兩種方式之JDK和cglib的動態代理
AOP的實現原理: 都是基於代理模式,都是生成一個大代理物件 靜態AOP: AspectJ實現的AOP, 將切面程式碼直接編譯到Java類檔案中 --- 實現: JDK提供的動態代理技術 動態AOP: 將切面程式碼進行動態織入實現的AOP --- Spring的AOP為動態
CGLIB 和 JDK生成動態代理類的區別
AOP 使用的設計模式就是代理模式,是對IOC設計的補充。為了擴充套件性,往往會加上反射,動態生成位元組碼,生成代理類。 這裡往往還會使用到DI,把代理的實現類通過依賴注入的方式,傳給代理工廠。 關於生成動態代理類的方式有兩種:JDK和CGLIB。 CGLIB,是一個開源工具。spring 和hibernat
Spring AOP 代理實現的兩種方式: JDK動態代理 和 Cglib框架動態代理
1.JDK動態代理 JDK API 內建 ---- 通過 Proxy類,為目標物件建立代理 (必須面向介面代理 ),此文中介面為UserDao,實現類為UserDaoImpl. public class UserDaoImpl implements UserDao {
簡單瞭解靜態代理,JDK提供的動態代理和cglib的動態代理
開發十年,就只剩下這套架構體系了! >>>
細說java動態代理和cglib的動態代理
提到代理,想必大家對設計模式中的靜態代理和動態代理都比較熟悉,小編之前在部落格中對動態和靜態代理進行了對比,這篇博文就只探討java動態代理和cglib動態代理之間的區別; ♚
基於JDK動態代理和CGLIB動態代理的區別
Spring事務管理,有二種實現方式:xml宣告式事務和註解式事務支援,這裡介紹下,使用註解式事務,使用JDK和CGLIB二種方式的區別: 一、基礎工作 例項SpringMVC + Spring4.3.8 + Mybatis3.2.6 + Logback 的專案,如下所示
【代理模式】jdk和cglib動態代理實現的區別
jdk和cglib動態代理實現的區別 1、jdk動態代理生成的代理類和委託類實現了相同的介面; 2、cglib動態代理中生成的位元組碼更加複雜,生成的代理類是委託類的子類,且不能處理被final關鍵字
JDK和CGLIB動態代理區別
轉自:https://blog.csdn.net/yhl_jxy/article/details/80635012 一 JDK和CGLIB動態代理原理 1、JDK動態代理 利用攔截器(攔截器必須實現InvocationHanlder)加上反射機制生成一個實現代理介面的匿名類, 在呼叫具體
jdk動態代理和cglib動態代理的區別
1、Jdk動態代理例項:JDK動態代理只能代理實現了介面的類,其他普通類不能實現。代理類會在newProxyInstance方法中生成 介面: package proxy.jdk; public interface BookFacade { public void
cglib動態代理和jdk動態代理的區別與應用
1,引入 如果從一個Controller呼叫Service的非事務方法a,然後在a裡呼叫事務方法b,b事務生效嗎? public void update() { updateActual(); int a = 1 / 0;
java動態代理(JDK和CGLIB)筆記
動態代理:為一堆interface或類的實現提供統一的執行通道,從含義上就像區域網電腦通過代理上網一樣,走統一的通道,代理控制通道,自然可以在通道里加上自定義實現,例如像AOP切面,日誌等。 JDK的動態代理只能對介面實現,代理類需要實現InvocationHandler 介面。 一、介面 pub
Java動態代理(JDK 和CGLIB、Javassist、ASM之間的差別)
import com.foo.proxy.Rechargable; import com.foo.proxy.Vehicle; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; im
代理設計模式 (靜態代理設計模式)+ 動態代理(JDK和Cglib)
一、代理設計模式 1、設計模式:前人總結一套解決特定問題的程式碼 2、代理設計模式優點: 2.1 保護真實物件 2.2 讓真實物件職責更明確 2.3 擴充套件 3、代理設計模式 3.1 真實物件(老總) 3.2 代理物件(祕書) 3.3 抽象物
java動態代理——JDK和CGLIB原理解析與使用
CGLIB的動態代理 原理 代理為控制要訪問的目標物件提供了一種途徑。當訪問物件時,它引入了一個間接的層。JDK自從1.3版本開始,就引入了動態代理,並且經常被用來動態地建立代理。JDK的動態代理用起來非常簡單,當它有一個限制,就是使用動
java動態代理(JDK和cglib)
JAVA的動態代理 代理模式 代理模式是常用的java設計模式,他的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理訊息等。代理類與委託類之間通常會存在關聯關係,一個代理類的物件與一個委託類的物件關聯,代理類的物件本身並不真正實現服務,
使用JDK和Cglib兩種方式動態代理
一 使用JDK動態代理這種方式,只能對介面進行動態代理,有一定的侷限性;介面:package org.spring.test2; import java.util.Map; public interface UserService { void insert(Map&l
JDK和CGLIB動態代理原理
一 JDK和CGLIB動態代理原理 1、JDK動態代理 利用攔截器(攔截器必須實現InvocationHanlder)加上反射機制生成一個實現代理介面的匿名類, 在呼叫具體方法前呼叫InvokeHandler來處理。 2、CGLiB動態代理 利用ASM開源包,對代理物件類的class檔案載入
Spring AOP中的JDK和CGLib動態代理哪個效率更高?
一、背景 今天有小夥伴面試的時候被問到:Spring AOP中JDK 和 CGLib動態代理哪個效率更高? 二、基本概念 首先,我們知道Spring AOP的底層實現有兩種方式:一種是JDK動態代理,另一種是CGLib的方式。 自Java 1.3以後
Sping-AOP:cglib動態代理與JDK動態代理的區別
預設狀態下,Spring-AOP預設使用JDK動態代理,當需要代理的物件沒有實現任何介面時,才使用cglib動態代理。 下面,將向大家介紹JDK動態代理和Cglib動態代理的使用、兩者的區別已經注意事項。 一、JDK動態代理 由於JDK動態代理是基於介