本系列文章均整理自我在先前一家公司的CGLib使用總結(jié)和筆記。分享出來,希望對看到的人有所幫助,同時歡迎大家提出寶貴意見。如需轉(zhuǎn)載,請勿修改,且注明作者shensy及出處。 實戰(zhàn)CGLib系列文章 本篇介紹通過MethodInterceptor和Enhancer實現(xiàn)一個動態(tài)代理。 一、首先說一下JDK中的動態(tài)代理: JDK中的動態(tài)代理是通過反射類Proxy以及InvocationHandler回調(diào)接口實現(xiàn)的,不了解的同學(xué)請參考我的這篇Blog:Java動態(tài)代理詳解 http://shensy./blog/1698197 但是,JDK中所要進行動態(tài)代理的類必須要實現(xiàn)一個接口,也就是說只能對該類所實現(xiàn)接口中定義的方法進行代理,這在實際編程中具有一定的局限性,而且使用反射的效率也并不是很高。 二、使用CGLib實現(xiàn): 使用CGLib實現(xiàn)動態(tài)代理,完全不受代理類必須實現(xiàn)接口的限制,而且CGLib底層采用ASM字節(jié)碼生成框架,使用字節(jié)碼技術(shù)生成代理類,比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的方法進行代理,因為CGLib原理是動態(tài)生成被代理類的子類。 下面,將通過一個實例介紹使用CGLib實現(xiàn)動態(tài)代理。 1、被代理類: 首先,定義一個類,該類沒有實現(xiàn)任何接口,包含兩個方法。 Java代碼
2、攔截器: 定義一個攔截器。在調(diào)用目標(biāo)方法時,CGLib會回調(diào)MethodInterceptor接口方法攔截,來實現(xiàn)你自己的代理邏輯,類似于JDK中的InvocationHandler接口。 Java代碼
參數(shù):Object為由CGLib動態(tài)生成的代理類實例,Method為上文中實體類所調(diào)用的被代理的方法引用,Object[]為參數(shù)值列表,MethodProxy為生成的代理類對方法的代理引用。 返回:從代理實例的方法調(diào)用返回的值。 其中,proxy.invokeSuper(obj,arg): 調(diào)用代理類實例上的proxy方法的父類方法(即實體類ConcreteClassNoInterface中對應(yīng)的方法) 在這個示例中,只在調(diào)用被代理類方法前后各打印了一句話,當(dāng)然實際編程中可以是其它復(fù)雜邏輯。 3、生成動態(tài)代理類: Java代碼
這里Enhancer類是CGLib中的一個字節(jié)碼增強器,它可以方便的對你想要處理的類進行擴展,以后會經(jīng)??吹剿?。 首先將被代理類ConcreteClassNoInterface設(shè)置成父類,然后設(shè)置攔截器ConcreteClassInterceptor,最后執(zhí)行enhancer.create()動態(tài)生成一個代理類,并從Object強制轉(zhuǎn)型成父類型ConcreteClassNoInterface。 最后,在代理類上調(diào)用方法: Java代碼
查看控制臺輸出: 控制臺代碼
可以看到,攔截器在調(diào)用被代理類方法前后都執(zhí)行了print操作。 結(jié)束語: 以上就是CGLib實現(xiàn)動態(tài)代理的一個示例,本系列后面將繼續(xù)介紹CGLib的強大功能,敬請期待。 |
|