Java CGLib動(dòng)態(tài)代理機(jī)制(全面解析)
一、首先說(shuō)一下JDK中的動(dòng)態(tài)代理:
JDK中的動(dòng)態(tài)代理是通過(guò)反射類(lèi)Proxy以及InvocationHandler回調(diào)接口實(shí)現(xiàn)的
但是,JDK中所要進(jìn)行動(dòng)態(tài)代理的類(lèi)必須要實(shí)現(xiàn)一個(gè)接口,也就是說(shuō)只能對(duì)該類(lèi)所實(shí)現(xiàn)接口中定義的方法進(jìn)行代理,這在實(shí)際編程中具有一定的局限性,而且使用反射的效率也并不是很高。
二、使用CGLib實(shí)現(xiàn):
使用CGLib實(shí)現(xiàn)動(dòng)態(tài)代理,完全不受代理類(lèi)必須實(shí)現(xiàn)接口的限制,而且CGLib底層采用ASM字節(jié)碼生成框架,使用字節(jié)碼技術(shù)生成代理類(lèi),比使用Java反射效率要高。唯一需要注意的是,CGLib不能對(duì)聲明為final的方法進(jìn)行代理,因?yàn)镃GLib原理是動(dòng)態(tài)生成被代理類(lèi)的子類(lèi)。
下面,將通過(guò)一個(gè)實(shí)例介紹使用CGLib實(shí)現(xiàn)動(dòng)態(tài)代理。
1、被代理類(lèi):
首先,定義一個(gè)類(lèi),該類(lèi)沒(méi)有實(shí)現(xiàn)任何接口,包含兩個(gè)方法。
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、攔截器:
定義一個(gè)攔截器。在調(diào)用目標(biāo)方法時(shí),CGLib會(huì)回調(diào)MethodInterceptor接口方法攔截,來(lái)實(shí)現(xiàn)你自己的代理邏輯,類(lèi)似于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;
}
}
參數(shù):Object為由CGLib動(dòng)態(tài)生成的代理類(lèi)實(shí)例,Method為上文中實(shí)體類(lèi)所調(diào)用的被代理的方法引用,Object[]為參數(shù)值列表,MethodProxy為生成的代理類(lèi)對(duì)方法的代理引用。
返回:從代理實(shí)例的方法調(diào)用返回的值。
其中,proxy.invokeSuper(obj,arg):
調(diào)用代理類(lèi)實(shí)例上的proxy方法的父類(lèi)方法(即實(shí)體類(lèi)ConcreteClassNoInterface中對(duì)應(yīng)的方法)
在這個(gè)示例中,只在調(diào)用被代理類(lèi)方法前后各打印了一句話,當(dāng)然實(shí)際編程中可以是其它復(fù)雜邏輯。
3、生成動(dòng)態(tài)代理類(lèi):
Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(ConcreteClassNoInterface.class); enhancer.setCallback(new ConcreteClassInterceptor()); ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create();
這里Enhancer類(lèi)是CGLib中的一個(gè)字節(jié)碼增強(qiáng)器,它可以方便的對(duì)你想要處理的類(lèi)進(jìn)行擴(kuò)展,以后會(huì)經(jīng)常看到它。
首先將被代理類(lèi)ConcreteClassNoInterface設(shè)置成父類(lèi),然后設(shè)置攔截器ConcreteClassInterceptor,最后執(zhí)行enhancer.create()動(dòng)態(tài)生成一個(gè)代理類(lèi),并從Object強(qiáng)制轉(zhuǎn)型成父類(lèi)型ConcreteClassNoInterface。
最后,在代理類(lèi)上調(diào)用方法:
ccni.getConcreteMethodA("shensy");
ccni.getConcreteMethodB(0);
查看控制臺(tái)輸出:
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)
可以看到,攔截器在調(diào)用被代理類(lèi)方法前后都執(zhí)行了print操作。
以上這篇Java CGLib動(dòng)態(tài)代理機(jī)制(全面解析)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java基礎(chǔ)之動(dòng)態(tài)代理Cglib詳解
- 詳解Java Cglib動(dòng)態(tài)代理
- Java使用JDK與Cglib動(dòng)態(tài)代理技術(shù)統(tǒng)一管理日志記錄
- JAVA中的靜態(tài)代理、動(dòng)態(tài)代理以及CGLIB動(dòng)態(tài)代理總結(jié)
- java 中動(dòng)態(tài)代理(JDK,cglib)實(shí)例代碼
- 深入理解java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式(JDK/Cglib)
- Java 動(dòng)態(tài)代理與CGLIB詳細(xì)介紹
- 淺談Java代理(jdk靜態(tài)代理、動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理)
- java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例分享
- java動(dòng)態(tài)代理(jdk與cglib)詳細(xì)解析
- Java cglib動(dòng)態(tài)代理原理分析
相關(guān)文章
springboot如何讀取配置文件(application.yml)中的屬性值
本篇文章主要介紹了springboot如何讀取配置文件(application.yml)中的屬性值,具有一定的參考價(jià)值,有興趣的小伙伴可以了解一下2017-04-04
java基于servlet編寫(xiě)上傳下載功能 類(lèi)似文件服務(wù)器
這篇文章主要為大家詳細(xì)介紹了java基于servlet編寫(xiě)上傳下載功能,類(lèi)似文件服務(wù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
Java實(shí)現(xiàn)給微信群中定時(shí)推送消息
這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)給微信群中定時(shí)推送消息的功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下2022-12-12
java根據(jù)List內(nèi)對(duì)象的屬性排序方法
下面小編就為大家分享一篇java根據(jù)List內(nèi)對(duì)象的屬性排序方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Java使用FTPClient類(lèi)讀寫(xiě)FTP
這篇文章主要為大家詳細(xì)介紹了Java使用FTPClient類(lèi)讀寫(xiě)FTP的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
java web實(shí)現(xiàn)網(wǎng)上手機(jī)銷(xiāo)售系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java web實(shí)現(xiàn)網(wǎng)上手機(jī)銷(xiāo)售系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
判斷java文件類(lèi)型TikaToolKit的實(shí)例
這篇文章主要介紹了判斷java文件類(lèi)型TikaToolKit的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10

