更新時(shí)間:2018-06-29 來(lái)源:黑馬程序員JavaEE培訓(xùn)學(xué)院 瀏覽量:
概念
靜態(tài)代理
動(dòng)態(tài)代理
cglib代理
概念
代理模式:代理模式,顧名思義,肯定跟代理有很大的聯(lián)系,代理的意思即是通過(guò)訪問(wèn)其他目標(biāo)進(jìn)行操作來(lái)代替直接操作目標(biāo)對(duì)象,也就是通過(guò)代理對(duì)象來(lái)訪問(wèn)目標(biāo)對(duì)象。
好處:這樣做的好處是可以再目標(biāo)對(duì)象的基礎(chǔ)上,增強(qiáng)額外的功能操作,即擴(kuò)展目標(biāo)對(duì)象的功能。
使用代理模式的原因:
中介隔離作用:在某些情況下,一個(gè)客戶(hù)類(lèi)不想或者不能直接引用一個(gè)委托對(duì)象,而代理類(lèi)對(duì)象可以在客戶(hù)類(lèi)和委托對(duì)象之間起到中介的作用,其特征是代理類(lèi)和委托類(lèi)實(shí)現(xiàn)相同的接口。
開(kāi)閉原則,增加功能:代理類(lèi)除了是客戶(hù)類(lèi)和委托類(lèi)的中介之外,我們還可以通過(guò)給代理類(lèi)增加額外的功能來(lái)擴(kuò)展委托類(lèi)的功能,這樣做我們只需要修改代理類(lèi)而不需要再修改委托類(lèi),符合代碼設(shè)計(jì)的開(kāi)閉原則。代理類(lèi)主要負(fù)責(zé)為委托類(lèi)預(yù)處理消息、過(guò)濾消息、把消息轉(zhuǎn)發(fā)給委托類(lèi),以及事后對(duì)返回結(jié)果的處理等。代理類(lèi)本身并不真正實(shí)現(xiàn)服務(wù),而是同過(guò)調(diào)用委托類(lèi)的相關(guān)方法,來(lái)提供特定的服務(wù)。真正的業(yè)務(wù)功能還是由委托類(lèi)來(lái)實(shí)現(xiàn),但是可以在業(yè)務(wù)功能執(zhí)行的前后加入一些公共的服務(wù)。例如我們想給項(xiàng)目加入緩存、日志這些功能,我們就可以使用代理類(lèi)來(lái)完成,而沒(méi)必要打開(kāi)已經(jīng)封裝好的委托類(lèi)。
靜態(tài)代理
靜態(tài)代理需要與目標(biāo)對(duì)象繼承相同的接口
靜態(tài)代理總結(jié):
1.可以做到在不修改目標(biāo)對(duì)象的功能前提下,對(duì)目標(biāo)功能擴(kuò)展。
2.缺點(diǎn):因?yàn)榇韺?duì)象需要與目標(biāo)對(duì)象實(shí)現(xiàn)一樣的接口,所以會(huì)有很多代理類(lèi),類(lèi)太多.同時(shí),一旦接口增加方法,目標(biāo)對(duì)象與代理對(duì)象都要維護(hù).
動(dòng)態(tài)代理
動(dòng)態(tài)代理主要是通過(guò)反射機(jī)制來(lái)獲取目標(biāo)對(duì)象的接口方法。
動(dòng)態(tài)代理有以下特點(diǎn):
1.代理對(duì)象,不需要實(shí)現(xiàn)接口 。
2.代理對(duì)象的生成,是利用JDK的API,動(dòng)態(tài)的在內(nèi)存中構(gòu)建代理對(duì)象(需要我們指定創(chuàng)代理對(duì)象/目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類(lèi)型) 3.動(dòng)態(tài)代理也叫做:JDK代理,接口代理。
cglib代理
上面的靜態(tài)代理和動(dòng)態(tài)代理模式都是要求目標(biāo)對(duì)象是實(shí)現(xiàn)一個(gè)接口的目標(biāo)對(duì)象,但是有時(shí)候目標(biāo)對(duì)象只是一個(gè)單獨(dú)的對(duì)象,并沒(méi)有實(shí)現(xiàn)任何的接口,這個(gè)時(shí)候就可以使用以目標(biāo)對(duì)象子類(lèi)的方式類(lèi)實(shí)現(xiàn)代理,這種方法就叫做:Cglib代理
Cglib代理,也叫作子類(lèi)代理,它是在內(nèi)存中構(gòu)建一個(gè)子類(lèi)對(duì)象從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象功能的擴(kuò)展。
JDK的動(dòng)態(tài)代理有一個(gè)限制,就是使用動(dòng)態(tài)代理的對(duì)象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口,如果想代理沒(méi)有實(shí)現(xiàn)接口的類(lèi),就可以使用Cglib實(shí)現(xiàn)。
Cglib是一個(gè)強(qiáng)大的高性能的代碼生成包,它可以在運(yùn)行期擴(kuò)展java類(lèi)與實(shí)現(xiàn)java接口.它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)
Cglib包的底層是通過(guò)使用一個(gè)小而塊的字節(jié)碼處理框架ASM來(lái)轉(zhuǎn)換字節(jié)碼并生成新的類(lèi).不鼓勵(lì)直接使用ASM,因?yàn)樗竽惚仨殞?duì)JVM內(nèi)部結(jié)構(gòu)包括class文件的格式和指令集都很熟悉。
Cglib子類(lèi)代理實(shí)現(xiàn)方法:
1.需要引入cglib的jar文件,但是Spring的核心包中已經(jīng)包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可
2.引入功能包后,就可以在內(nèi)存中動(dòng)態(tài)構(gòu)建子類(lèi)
3.代理的類(lèi)不能為final,否則報(bào)錯(cuò)
4.目標(biāo)對(duì)象的方法如果為final/static,那么就不會(huì)被攔截,即不會(huì)執(zhí)行目標(biāo)對(duì)象額外的業(yè)務(wù)方法
本文版權(quán)歸黑馬程序員JavaEE學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
首發(fā):http://java.itheima.com/