基于jdk動態(tài)代理和cglib動態(tài)代理實現(xiàn)及區(qū)別說明
jdk動態(tài)代理和cglib動態(tài)代理實現(xiàn)及區(qū)別
代理模式是一種設(shè)計模式,提供了對目標對象額外的訪問方式,即通過代理對象訪問目標對象,這樣可以在不修改原目標對象的前提下,提供額外的功能操作,擴展目標對象的功能。
代理模式又分為:
- 靜態(tài)代理
- jdk動態(tài)代理
- cglib動態(tài)代理
- 由于靜態(tài)代理會產(chǎn)生過多的代理類,一旦接口增加方法,目標對象與代理對象都要進行修改,不易維護。
- 而動態(tài)代理是動態(tài)地在內(nèi)存中構(gòu)建代理對象,從而實現(xiàn)對目標對象的代理功能,接口增加方法時代理對象不受影響 。
下面我們講講jdk動態(tài)代理和cglib動態(tài)代理實現(xiàn)及區(qū)別
jdk動態(tài)代理實現(xiàn)
@Test
public void test(){
? ? IPerson target = new ManPerson();
? ? IPerson proxy = (IPerson)Proxy.newProxyInstance(
? ? ? ? target.getClass().getClassLoader(),?
? ? ? ? target.getClass().getInterfaces(),?
? ? ? ? new PersonInvocationHandler(target));
? ? proxy.eat();
? ? proxy.sleep();
}
// 代理對象
class PersonInvocationHandler implements InvocationHandler{
? ? private Object target;
? ? public PersonInvocationHandler(Object target){
? ? ? ? this.target = target;
? ? }
? ? @Override
? ? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
? ? ? ? System.out.println("start");
?? ?Object result = method.invoke(target, args);
?? ?System.out.println("end");
?? ?return result;
? ? }
}
// 目標對象
class ManPerson implements IPerson{
? ? @Override
? ? public void eat(){
?? ?System.out.println("吃飯中......");
? ? }
? ? @Override
? ? public void sleep(){
?? ?System.out.println("睡覺中......");
? ? }
}
// 目標對象接口
interface IPerson{
? ? void eat();
? ? void sleep();
}cglib動態(tài)代理
@Test
public void test(){
? ? Person proxy = (Person)Enhancer.create(Person.class, new PersonMethodInterceptor());
? ? proxy.eat();
? ? proxy.sleep();
}
// 代理對象
class PersonMethodInterceptor implements MethodInterceptor{
? ? @Override
? ? public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable{
? ? ? ? System.out.println("start");
?? ?Object result = methodProxy.invokeSuper(o, objects);
?? ?System.out.println("end");
?? ?return result;
? ? }
}目標對象
public class Person{
? ? public void eat(){
?? ?System.out.println("吃飯中......");
? ? }
? ? public void sleep(){
?? ?System.out.println("睡覺中......");
? ? }
}區(qū)別
1.JDK動態(tài)代理是實現(xiàn)了被代理對象的接口,Cglib是繼承了被代理對象。
2.JDK和Cglib都是在運行期生成字節(jié)碼,JDK是直接寫Class字節(jié)碼,Cglib使用ASM框架寫Class字節(jié)碼,Cglib代理實現(xiàn)更復雜,生成代理類比JDK效率低。
3.JDK調(diào)用代理方法,是通過反射機制調(diào)用,Cglib是通過FastClass機制直接調(diào)用方法,Cglib執(zhí)行效率更高。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java線程安全問題小結(jié)_動力節(jié)點Java學院整理
這篇文章主要介紹了Java線程安全問題小結(jié)的相關(guān)資料,需要的朋友可以參考下2017-05-05
http調(diào)用controller方法時openfeign執(zhí)行流程
這篇文章主要為大家介紹了http調(diào)用controller方法時openfeign執(zhí)行流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
windows下使用 intellij idea 編譯 kafka 源碼環(huán)境
這篇文章主要介紹了使用 intellij idea 編譯 kafka 源碼的環(huán)境,本文是基于windows下做的項目演示,需要的朋友可以參考下2021-10-10

