1. 程式人生 > >JDK和CGLIB生成動態代理類的區別

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"/>

相關推薦

JDKCGLIB生成動態代理區別

 關於動態代理和靜態代理 當一個物件(客戶端)不能或者不想直接引用另一個物件(目標物件),這時可以應用代理模式在這兩者之間構建一個橋樑--代理物件。 按照代理物件的建立時期不同,可以分為兩種: 靜態代理:事先寫好代理物件類,在程式釋出前就已經存在了; 動態代理:應

Spring中AOP實現的兩種方式之JDKcglib動態代理

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 的專案,如下所示

代理模式】jdkcglib動態代理實現的區別

jdk和cglib動態代理實現的區別 1、jdk動態代理生成的代理類和委託類實現了相同的介面; 2、cglib動態代理中生成的位元組碼更加複雜,生成的代理類是委託類的子類,且不能處理被final關鍵字

JDKCGLIB動態代理區別

轉自: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動態代理JDKCGLIB)筆記

動態代理:為一堆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

代理設計模式 (靜態代理設計模式)+ 動態代理JDKCglib

一、代理設計模式 1、設計模式:前人總結一套解決特定問題的程式碼 2、代理設計模式優點:     2.1 保護真實物件     2.2 讓真實物件職責更明確     2.3 擴充套件 3、代理設計模式     3.1 真實物件(老總)     3.2 代理物件(祕書)     3.3 抽象物

java動態代理——JDKCGLIB原理解析與使用

CGLIB的動態代理  原理       代理為控制要訪問的目標物件提供了一種途徑。當訪問物件時,它引入了一個間接的層。JDK自從1.3版本開始,就引入了動態代理,並且經常被用來動態地建立代理。JDK的動態代理用起來非常簡單,當它有一個限制,就是使用動

java動態代理JDKcglib

JAVA的動態代理  代理模式  代理模式是常用的java設計模式,他的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理訊息等。代理類與委託類之間通常會存在關聯關係,一個代理類的物件與一個委託類的物件關聯,代理類的物件本身並不真正實現服務,

使用JDKCglib兩種方式動態代理

一 使用JDK動態代理這種方式,只能對介面進行動態代理,有一定的侷限性;介面:package org.spring.test2; import java.util.Map; public interface UserService { void insert(Map&l

JDKCGLIB動態代理原理

一 JDK和CGLIB動態代理原理 1、JDK動態代理 利用攔截器(攔截器必須實現InvocationHanlder)加上反射機制生成一個實現代理介面的匿名類, 在呼叫具體方法前呼叫InvokeHandler來處理。 2、CGLiB動態代理 利用ASM開源包,對代理物件類的class檔案載入

Spring AOP中的JDKCGLib動態代理哪個效率更高?

一、背景 今天有小夥伴面試的時候被問到:Spring AOP中JDK 和 CGLib動態代理哪個效率更高? 二、基本概念 首先,我們知道Spring AOP的底層實現有兩種方式:一種是JDK動態代理,另一種是CGLib的方式。 自Java 1.3以後

Sping-AOP:cglib動態代理JDK動態代理區別

預設狀態下,Spring-AOP預設使用JDK動態代理,當需要代理的物件沒有實現任何介面時,才使用cglib動態代理。 下面,將向大家介紹JDK動態代理和Cglib動態代理的使用、兩者的區別已經注意事項。 一、JDK動態代理 由於JDK動態代理是基於介