首頁技術(shù)文章正文

Java設(shè)計(jì)模式之代理模式

更新時(shí)間:2018-06-29 來源:黑馬程序員JavaEE培訓(xùn)學(xué)院 瀏覽量:

 

概念

靜態(tài)代理

動態(tài)代理

cglib代理

概念

代理模式:代理模式,顧名思義,肯定跟代理有很大的聯(lián)系,代理的意思即是通過訪問其他目標(biāo)進(jìn)行操作來代替直接操作目標(biāo)對象,也就是通過代理對象來訪問目標(biāo)對象。

好處:這樣做的好處是可以再目標(biāo)對象的基礎(chǔ)上,增強(qiáng)額外的功能操作,即擴(kuò)展目標(biāo)對象的功能。

使用代理模式的原因:

中介隔離作用:在某些情況下,一個(gè)客戶類不想或者不能直接引用一個(gè)委托對象,而代理類對象可以在客戶類和委托對象之間起到中介的作用,其特征是代理類和委托類實(shí)現(xiàn)相同的接口。

開閉原則,增加功能:代理類除了是客戶類和委托類的中介之外,我們還可以通過給代理類增加額外的功能來擴(kuò)展委托類的功能,這樣做我們只需要修改代理類而不需要再修改委托類,符合代碼設(shè)計(jì)的開閉原則。代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后對返回結(jié)果的處理等。代理類本身并不真正實(shí)現(xiàn)服務(wù),而是同過調(diào)用委托類的相關(guān)方法,來提供特定的服務(wù)。真正的業(yè)務(wù)功能還是由委托類來實(shí)現(xiàn),但是可以在業(yè)務(wù)功能執(zhí)行的前后加入一些公共的服務(wù)。例如我們想給項(xiàng)目加入緩存、日志這些功能,我們就可以使用代理類來完成,而沒必要打開已經(jīng)封裝好的委托類。

靜態(tài)代理

靜態(tài)代理需要與目標(biāo)對象繼承相同的接口

靜態(tài)代理總結(jié):

1.可以做到在不修改目標(biāo)對象的功能前提下,對目標(biāo)功能擴(kuò)展。

2.缺點(diǎn):因?yàn)榇韺ο笮枰c目標(biāo)對象實(shí)現(xiàn)一樣的接口,所以會有很多代理類,類太多.同時(shí),一旦接口增加方法,目標(biāo)對象與代理對象都要維護(hù).

動態(tài)代理

動態(tài)代理主要是通過反射機(jī)制來獲取目標(biāo)對象的接口方法。

動態(tài)代理有以下特點(diǎn):

1.代理對象,不需要實(shí)現(xiàn)接口 。

2.代理對象的生成,是利用JDK的API,動態(tài)的在內(nèi)存中構(gòu)建代理對象(需要我們指定創(chuàng)代理對象/目標(biāo)對象實(shí)現(xiàn)的接口的類型) 3.動態(tài)代理也叫做:JDK代理,接口代理。

 

cglib代理

上面的靜態(tài)代理和動態(tài)代理模式都是要求目標(biāo)對象是實(shí)現(xiàn)一個(gè)接口的目標(biāo)對象,但是有時(shí)候目標(biāo)對象只是一個(gè)單獨(dú)的對象,并沒有實(shí)現(xiàn)任何的接口,這個(gè)時(shí)候就可以使用以目標(biāo)對象子類的方式類實(shí)現(xiàn)代理,這種方法就叫做:Cglib代理

Cglib代理,也叫作子類代理,它是在內(nèi)存中構(gòu)建一個(gè)子類對象從而實(shí)現(xiàn)對目標(biāo)對象功能的擴(kuò)展。

JDK的動態(tài)代理有一個(gè)限制,就是使用動態(tài)代理的對象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口,如果想代理沒有實(shí)現(xiàn)接口的類,就可以使用Cglib實(shí)現(xiàn)。

Cglib是一個(gè)強(qiáng)大的高性能的代碼生成包,它可以在運(yùn)行期擴(kuò)展java類與實(shí)現(xiàn)java接口.它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)

Cglib包的底層是通過使用一個(gè)小而塊的字節(jié)碼處理框架ASM來轉(zhuǎn)換字節(jié)碼并生成新的類.不鼓勵(lì)直接使用ASM,因?yàn)樗竽惚仨殞VM內(nèi)部結(jié)構(gòu)包括class文件的格式和指令集都很熟悉。

Cglib子類代理實(shí)現(xiàn)方法:

1.需要引入cglib的jar文件,但是Spring的核心包中已經(jīng)包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可

2.引入功能包后,就可以在內(nèi)存中動態(tài)構(gòu)建子類

3.代理的類不能為final,否則報(bào)錯(cuò)

4.目標(biāo)對象的方法如果為final/static,那么就不會被攔截,即不會執(zhí)行目標(biāo)對象額外的業(yè)務(wù)方法


本文版權(quán)歸黑馬程序員JavaEE學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!

作者:黑馬程序員JavaEE培訓(xùn)學(xué)院

首發(fā):http://java.itheima.com/

分享到:
在線咨詢 我要報(bào)名
和我們在線交談!