靜態(tài)代理
靜態(tài)代理相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,無(wú)非就是聚合+多態(tài):
參考:設(shè)計(jì)模式筆記 – Proxy 代理模式 (Design Pattern)
動(dòng)態(tài)代理
我們知道,通過(guò)使用代理,可以在被代理的類(lèi)的方法的前后添加一些處理方法,這樣就達(dá)到了類(lèi)似AOP的效果。而JDK中提供的動(dòng)態(tài)代理,就是實(shí)現(xiàn)AOP的絕好底層技術(shù)。
JDK動(dòng)態(tài)代理
JDK動(dòng)態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個(gè)類(lèi):Proxy和InvocationHandler。InvocationHandler是一個(gè)接口,通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類(lèi)的代碼,動(dòng)態(tài)將橫切邏輯和業(yè)務(wù)邏輯編制在一起。
Proxy利用InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類(lèi)的代理對(duì)象。
例子:Java筆記 – 反射 動(dòng)態(tài)代理
CGLib動(dòng)態(tài)代理
還有一個(gè)叫CGLib的動(dòng)態(tài)代理,CGLib全稱(chēng)為Code Generation Library,是一個(gè)強(qiáng)大的高性能,高質(zhì)量的代碼生成類(lèi)庫(kù),可以在運(yùn)行期擴(kuò)展Java類(lèi)與實(shí)現(xiàn)Java接口,CGLib封裝了asm,可以再運(yùn)行期動(dòng)態(tài)生成新的class。和JDK動(dòng)態(tài)代理相比較:JDK創(chuàng)建代理有一個(gè)限制,就是只能為接口創(chuàng)建代理實(shí)例,而對(duì)于沒(méi)有通過(guò)接口定義業(yè)務(wù)方法的類(lèi),則可以通過(guò)CGLib創(chuàng)建動(dòng)態(tài)代理。
CGLib采用非常底層的字節(jié)碼技術(shù),可以為一個(gè)類(lèi)創(chuàng)建子類(lèi),并在子類(lèi)中采用方法攔截的技術(shù)攔截所有父類(lèi)方法的調(diào)用,并順勢(shì)織入橫切邏輯。
JDK動(dòng)態(tài)代理和CGLib的比較
CGLib所創(chuàng)建的動(dòng)態(tài)代理對(duì)象的性能比JDK所創(chuàng)建的代理對(duì)象性能高不少,大概10倍,但CGLib在創(chuàng)建代理對(duì)象時(shí)所花費(fèi)的時(shí)間卻比JDK動(dòng)態(tài)代理多大概8倍,所以對(duì)于singleton的代理對(duì)象或者具有實(shí)例池的代理,因?yàn)闊o(wú)需頻繁的創(chuàng)建新的實(shí)例,所以比較適合CGLib動(dòng)態(tài)代理技術(shù),反之則適用于JDK動(dòng)態(tài)代理技術(shù)。另外,由于CGLib采用動(dòng)態(tài)創(chuàng)建子類(lèi)的方式生成代理對(duì)象,所以不能對(duì)目標(biāo)類(lèi)中的final,private等方法進(jìn)行處理。所以,大家需要根據(jù)實(shí)際的情況選擇使用什么樣的代理了。
同樣的,Spring的AOP編程中相關(guān)的ProxyFactory代理工廠內(nèi)部就是使用JDK動(dòng)態(tài)代理或CGLib動(dòng)態(tài)代理的,通過(guò)動(dòng)態(tài)代理,將增強(qiáng)(advice)應(yīng)用到目標(biāo)類(lèi)中。
JDK動(dòng)態(tài)代理主要用到j(luò)ava.lang.reflect包中的兩個(gè)類(lèi):Proxy和InvocationHandler.
InvocationHandler是一個(gè)接口,通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類(lèi)的代碼,動(dòng)態(tài)的將橫切邏輯和業(yè)務(wù)邏輯編織在一起。
Proxy利用InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類(lèi)的代理對(duì)象。