Java CGLib動態(tài)代理機制(全面解析)
一、首先說一下JDK中的動態(tài)代理:
JDK中的動態(tài)代理是通過反射類Proxy以及InvocationHandler回調接口實現的
但是,JDK中所要進行動態(tài)代理的類必須要實現一個接口,也就是說只能對該類所實現接口中定義的方法進行代理,這在實際編程中具有一定的局限性,而且使用反射的效率也并不是很高。
二、使用CGLib實現:
使用CGLib實現動態(tài)代理,完全不受代理類必須實現接口的限制,而且CGLib底層采用ASM字節(jié)碼生成框架,使用字節(jié)碼技術生成代理類,比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的方法進行代理,因為CGLib原理是動態(tài)生成被代理類的子類。
下面,將通過一個實例介紹使用CGLib實現動態(tài)代理。
1、被代理類:
首先,定義一個類,該類沒有實現任何接口,包含兩個方法。
public class ConcreteClassNoInterface {
public String getConcreteMethodA(String str){
System.out.println("ConcreteMethod A ... "+str);
return str;
}
public int getConcreteMethodB(int n){
System.out.println("ConcreteMethod B ... "+n);
return n+10;
}
}
2、攔截器:
定義一個攔截器。在調用目標方法時,CGLib會回調MethodInterceptor接口方法攔截,來實現你自己的代理邏輯,類似于JDK中的InvocationHandler接口。
public class ConcreteClassInterceptor implements MethodInterceptor{
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
System.out.println("Before:"+method);
Object object=proxy.invokeSuper(obj, arg);
System.out.println("After:"+method);
return object;
}
}
參數:Object為由CGLib動態(tài)生成的代理類實例,Method為上文中實體類所調用的被代理的方法引用,Object[]為參數值列表,MethodProxy為生成的代理類對方法的代理引用。
返回:從代理實例的方法調用返回的值。
其中,proxy.invokeSuper(obj,arg):
調用代理類實例上的proxy方法的父類方法(即實體類ConcreteClassNoInterface中對應的方法)
在這個示例中,只在調用被代理類方法前后各打印了一句話,當然實際編程中可以是其它復雜邏輯。
3、生成動態(tài)代理類:
Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(ConcreteClassNoInterface.class); enhancer.setCallback(new ConcreteClassInterceptor()); ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create();
這里Enhancer類是CGLib中的一個字節(jié)碼增強器,它可以方便的對你想要處理的類進行擴展,以后會經常看到它。
首先將被代理類ConcreteClassNoInterface設置成父類,然后設置攔截器ConcreteClassInterceptor,最后執(zhí)行enhancer.create()動態(tài)生成一個代理類,并從Object強制轉型成父類型ConcreteClassNoInterface。
最后,在代理類上調用方法:
ccni.getConcreteMethodA("shensy");
ccni.getConcreteMethodB(0);
查看控制臺輸出:
Before :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String) ConcreteMethod A ... shensy After :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String) Before :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int) ConcreteMethod B ... 0 After :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)
可以看到,攔截器在調用被代理類方法前后都執(zhí)行了print操作。
以上這篇Java CGLib動態(tài)代理機制(全面解析)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Java基礎之動態(tài)代理Cglib詳解
- 詳解Java Cglib動態(tài)代理
- Java使用JDK與Cglib動態(tài)代理技術統(tǒng)一管理日志記錄
- JAVA中的靜態(tài)代理、動態(tài)代理以及CGLIB動態(tài)代理總結
- java 中動態(tài)代理(JDK,cglib)實例代碼
- 深入理解java動態(tài)代理的兩種實現方式(JDK/Cglib)
- Java 動態(tài)代理與CGLIB詳細介紹
- 淺談Java代理(jdk靜態(tài)代理、動態(tài)代理和cglib動態(tài)代理)
- java動態(tài)代理和cglib動態(tài)代理示例分享
- java動態(tài)代理(jdk與cglib)詳細解析
- Java cglib動態(tài)代理原理分析
相關文章
Spring mvc整合tiles框架的簡單入門教程(maven)
這篇文章主要給大家介紹了關于Spring mvc整合tiles框架的簡單入門教程(maven),文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友可以參考借鑒,下面來一起看看詳細的介紹吧。2017-12-12
spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解
這篇文章主要給大家介紹了關于spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 聲明的相關資料,需要的朋友可以參考下2020-08-08

