Java中JDK動(dòng)態(tài)代理的超詳細(xì)講解
1. 什么是動(dòng)態(tài)代理?
動(dòng)態(tài)代理是通過(guò)創(chuàng)建代理對(duì)象,在不改變?cè)写a的基礎(chǔ)上,給程序增加新的功能,實(shí)現(xiàn)了程序的功能增強(qiáng)。
2.動(dòng)態(tài)代理的實(shí)現(xiàn)方式有幾種?
- JDK動(dòng)態(tài)代理
- CGLB動(dòng)態(tài)代理
3. JDK動(dòng)態(tài)代理
使用了JDK中的InvocationHandler接口,Method類和Proxy類。JDK的動(dòng)態(tài)代理的要求:目標(biāo)類必須要有接口。(目標(biāo)類就是那個(gè)我們需要增強(qiáng)功能的方法所在的那個(gè)類,也是接口實(shí)現(xiàn)類所在的類)。我們通?;亟o目標(biāo)類中要增強(qiáng)的方法增加上日志,事務(wù)等非業(yè)務(wù)功能。
4. CGLB動(dòng)態(tài)代理
CGLB動(dòng)態(tài)代理即Code Generation Library,是一個(gè)開(kāi)源的第三方工具庫(kù),其原理是繼承,去生成目標(biāo)類的子類對(duì)象,這樣對(duì)子類的功能進(jìn)行增強(qiáng)。但是要求:目標(biāo)類不能用final修飾,目標(biāo)類中的方法也不能被final修飾。
5.動(dòng)態(tài)代理的效率
CGLB動(dòng)態(tài)代理的效率要大于JDK動(dòng)態(tài)代理的效率。
6.為什么要使用動(dòng)態(tài)代理呢?
設(shè)計(jì)出來(lái)動(dòng)態(tài)代理是為了解決一定的需求,因?yàn)樵谖覀儗?shí)際的開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)遇到,要給寫好的某個(gè)方法的前面或者是后面增加方法,甚至是給好幾個(gè)類的方法增加新的功能。若是我們直接在方法上寫上新的增加的方法,就會(huì)顯得很亂,而且很冗余。
那么我們初步改進(jìn)可以通過(guò)寫一個(gè)工具類去解決,在一個(gè)工具類中寫上我們要增強(qiáng)的方法,但是要求這些增強(qiáng)的方法是靜態(tài)修飾的,這樣我們就可以在原有的代碼上,使用類名.方法名的方式,來(lái)給原有的功能增加新的功能。這樣一定程度上的解決了代碼混亂的程度,但是還是不太完美。
再次改進(jìn):這個(gè)時(shí)候就是使用動(dòng)態(tài)代理。
這就體現(xiàn)了動(dòng)態(tài)代理的優(yōu)勢(shì),即在不修改任何原有代碼的情況下,實(shí)現(xiàn)給原有功能的增強(qiáng)。
7. JDK動(dòng)態(tài)代理詳細(xì)使用介紹
由于我們?cè)贘ava項(xiàng)目中,直接使用動(dòng)態(tài)代理的地方不多,所以我們都是使用的aspectj框架中寫好的動(dòng)態(tài)代理。aspectj框架中的動(dòng)態(tài)代理就是封裝的JDK動(dòng)態(tài)代理。
下面將仔細(xì)介紹使用JDK動(dòng)態(tài)代理的步驟:
- 最好可以先創(chuàng)建一個(gè)工具類,將要增強(qiáng)的功能先寫好,這樣我們便可以一句代碼能調(diào)動(dòng)這個(gè)用來(lái)增強(qiáng)的功能。
- 自定義類,去實(shí)現(xiàn)InvocationHandler接口,并且,重寫invoke()方法。
- 在這個(gè)自定義的類中,添加Objeck屬性,并且寫上有參的構(gòu)造方法。
- 在invoke()方法中寫上如下代碼

然后去主類中,使用動(dòng)態(tài)代理,實(shí)現(xiàn)功能的增強(qiáng)。

注意:
上面的JDK動(dòng)態(tài)代理的原理是反射機(jī)制。
我們可以使用proxy.getClass().getName()看到的值為com.sun.proxy.$Proxy
總結(jié)
到此這篇關(guān)于Java中JDK動(dòng)態(tài)代理的文章就介紹到這了,更多相關(guān)Java JDK動(dòng)態(tài)代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何通過(guò)Java實(shí)現(xiàn)類似Nginx代理
最近遇到一個(gè)問(wèn)題,在內(nèi)網(wǎng)環(huán)境中部署的項(xiàng)目需要調(diào)用外網(wǎng)完成一些應(yīng)用,一般情況我們可以通過(guò)增加一臺(tái)機(jī)器,部署到可以訪問(wèn)外網(wǎng)的服務(wù)器上,然后內(nèi)網(wǎng)直接連接該機(jī)器通過(guò)Nginx進(jìn)行代理即可,所以本文介紹了如何通過(guò)Java實(shí)現(xiàn)類似Nginx代理,需要的朋友可以參考下2024-08-08
Java在長(zhǎng)字符串中查找短字符串的實(shí)現(xiàn)多種方法
這篇文章主要介紹了Java在長(zhǎng)字符串中查找短字符串的實(shí)現(xiàn)多種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Java實(shí)現(xiàn)經(jīng)典游戲超級(jí)瑪麗的示例代碼
在你的童年記憶里,是否有一個(gè)蹦跳、頂蘑菇的小人?本文將用java語(yǔ)言實(shí)現(xiàn)經(jīng)典游戲《超級(jí)瑪麗》,文中采用了swing技術(shù)進(jìn)行了界面化處理,需要的可以參考一下2022-02-02
springboot后端配置多個(gè)數(shù)據(jù)源、Mysql數(shù)據(jù)庫(kù)的便捷方法
實(shí)現(xiàn)springboot 后端配置多個(gè)數(shù)據(jù)源、Mysql數(shù)據(jù)庫(kù),只需要新建 Mapper、實(shí)體類 相應(yīng)的文件夾,將不同數(shù)據(jù)源的文件保存到對(duì)應(yīng)的文件夾下,添加綁定數(shù)據(jù)庫(kù)配置Config,就可以輕松完成2021-08-08
JavaEE中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
這篇文章主要為大家詳細(xì)介紹了JavaEE中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例,感興趣的小伙伴們可以參考一下2016-05-05

