摘要:在代理實(shí)例上調(diào)用方法時(shí),方法調(diào)用將被轉(zhuǎn)發(fā)到的方法動(dòng)態(tài)代理實(shí)現(xiàn)的代理模式必須有一個(gè)的接口方法代理類實(shí)現(xiàn)類的實(shí)現(xiàn)方式是一個(gè)基于的字節(jié)碼生成庫,它允許我們在運(yùn)行時(shí)對字節(jié)碼進(jìn)行修改和動(dòng)態(tài)生成。
動(dòng)態(tài)代理是使用反射和字節(jié)碼的技術(shù),在運(yùn)行期創(chuàng)建指定接口或類的子類(動(dòng)態(tài)代理)以及其實(shí)例對象的技術(shù),通過這個(gè)技術(shù)可以無侵入性的為代碼進(jìn)行增強(qiáng)
Proxy:Proxy是所有動(dòng)態(tài)代理的父類,它提供了一個(gè)靜態(tài)方法來創(chuàng)建動(dòng)態(tài)代理的class對象和實(shí)例;
InvocationHandler:每個(gè)動(dòng)態(tài)代理實(shí)例都有一個(gè)關(guān)聯(lián)的InvocationHandler。 在代理實(shí)例上調(diào)用方法時(shí),方法調(diào)用將被轉(zhuǎn)發(fā)到InvocationHandler的invoke方法;
1.java 動(dòng)態(tài)代理實(shí)現(xiàn)
//java的代理模式必須有一個(gè)interface的接口方法 public interface ItemService { void sayHello(); } public class ItemServiceImpl implements ItemService { @Override public void sayHello() { System.out.println("hello world~"); } } //代理類 public class MyInvocationHandler implements InvocationHandler { private Object realObject; public void setRealObject(Object realObject) { this.realObject = realObject; } public Object getRealObject() { return realObject; } public MyInvocationHandler(Object realObject){ super(); this.realObject=realObject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before running ~~"); Object ret=method.invoke(realObject,args); System.out.println("after running ~~~"); return ret; } } // 實(shí)現(xiàn)類 public class main { public static void main(String[] args) { ItemService itemService=new ItemServiceImpl(); MyInvocationHandler handler=new MyInvocationHandler(itemService); ItemService proxy= (ItemService) Proxy.newProxyInstance(itemService.getClass().getClassLoader(),itemService.getClass().getInterfaces(),handler); proxy.sayHello(); } }
2.CGLIB的實(shí)現(xiàn)方式
CGLIB(Code Generation Library)是一個(gè)基于ASM的字節(jié)碼生成庫,它允許我們在運(yùn)行時(shí)對字節(jié)碼進(jìn)行修改和動(dòng)態(tài)生成。CGLIB通過繼承方式實(shí)現(xiàn)代理;
Enhancer:來指定要代理的目標(biāo)對象、實(shí)際處理代理邏輯的對象,最終通過調(diào)用create()方法得到代理對象,對這個(gè)對象所有非final方法的調(diào)用都會轉(zhuǎn)發(fā)給MethodInterceptor;
MethodInterceptor:動(dòng)態(tài)代理對象的方法調(diào)用都會轉(zhuǎn)發(fā)到intercept方法進(jìn)行增強(qiáng);
//1.需要引入//2.方法 public class ItemServiceImpl { void sayHello(String name) { System.out.println("hello world~"+name); } } //3.cglib代理實(shí)現(xiàn)類 public class MyInterceptor implements MethodInterceptor { private Object realObject; public void setRealObject(Object realObject) { this.realObject = realObject; } public Object getRealObject() { return realObject; } public MyInterceptor(Object realObject){ this.realObject=realObject; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before running ~~"); System.out.println(method); System.out.println(Arrays.toString(objects)); Object ret=methodProxy.invoke(realObject,objects); System.out.println("after running ~~"); return ret; } } //4.實(shí)現(xiàn)類 public class main { public static void main(String[] args) { ItemServiceImpl itemService=new ItemServiceImpl(); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(ItemServiceImpl.class); enhancer.setCallback(new MyInterceptor(itemService)); ItemServiceImpl imp= (ItemServiceImpl) enhancer.create(); imp.sayHello("張三"); } } cglib cglib 3.2.6
總結(jié):
JDK原生動(dòng)態(tài)代理是Java原生支持的,不需要任何外部依賴,但是它只能基于接口進(jìn)行代理;
CGLIB通過繼承的方式進(jìn)行代理,無論目標(biāo)對象有沒有實(shí)現(xiàn)接口都可以代理,但是無法處理final的情況
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73743.html
摘要:動(dòng)態(tài)代理又被稱為代理或接口代理。靜態(tài)代理在編譯時(shí)產(chǎn)生字節(jié)碼文件,可以直接使用,效率高。代理無需實(shí)現(xiàn)接口,通過生成類字節(jié)碼實(shí)現(xiàn)代理,比反射稍快,不存在性能問題,但會繼承目標(biāo)對象,需要重寫方法,所以目標(biāo)對象不能為類。 一、代理模式介紹 代理模式是一種設(shè)計(jì)模式,提供了對目標(biāo)對象額外的訪問方式,即通過代理對象訪問目標(biāo)對象,這樣可以在不修改原目標(biāo)對象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對象的功...
摘要:設(shè)計(jì)模式之代理模式今天學(xué)到的動(dòng)態(tài)代理實(shí)現(xiàn),對代理這個(gè)概念很模糊,看了一篇文章發(fā)現(xiàn)這是一種設(shè)計(jì)模式,于是學(xué)習(xí)記錄一下。簡介代理模式是一種對象結(jié)構(gòu)型的模式,主要為其他對象提供一種代理以控制對這個(gè)對象的訪問。下面依次講解著三種代理。 設(shè)計(jì)模式之代理模式 今天學(xué)到Spring的動(dòng)態(tài)代理實(shí)現(xiàn)AOP,對代理這個(gè)概念很模糊,看了一篇文章發(fā)現(xiàn)這是一種設(shè)計(jì)模式,于是學(xué)習(xí)記錄一下。 簡介 代理模式是一種對...
摘要:除了和外,我們還有最后一招我直接把一個(gè)代理類的源代碼用字符串拼出來,然后基于這個(gè)字符串調(diào)用的編譯期,動(dòng)態(tài)的創(chuàng)建一個(gè)新的文件,然后動(dòng)態(tài)編譯這個(gè)文件,這樣也能得到一個(gè)新的代理類。 面試問題:Java里的代理設(shè)計(jì)模式(Proxy Design Pattern)一共有幾種實(shí)現(xiàn)方式?這個(gè)題目很像孔乙己問茴香豆的茴字有哪幾種寫法? showImg(https://segmentfault.com/...
摘要:與靜態(tài)代理對比,動(dòng)態(tài)代理是在動(dòng)態(tài)生成代理類,由代理類完成對具體方法的封裝,實(shí)現(xiàn)的功能。本文將分析中兩種動(dòng)態(tài)代理的實(shí)現(xiàn)方式,和,比較它們的異同。那如何動(dòng)態(tài)編譯呢你可以使用,這是一個(gè)封裝了的庫,幫助你方便地實(shí)現(xiàn)動(dòng)態(tài)編譯源代碼。 發(fā)現(xiàn)Java面試很喜歡問Spring AOP怎么實(shí)現(xiàn)的之類的問題,所以寫一篇文章來整理一下。關(guān)于AOP和代理模式的概念這里并不做贅述,而是直奔主題,即AOP的實(shí)現(xiàn)方...
摘要:動(dòng)態(tài)代理的核心是接口和類。以上結(jié)果說明它生成的代理類為,說明是代理。測試前提實(shí)現(xiàn)接口測試類使用接口方式注入代理方式必須以接口方式注入測試配置為,運(yùn)行結(jié)果如下實(shí)際校驗(yàn)邏輯。。。。 本文也同步發(fā)布至簡書,地址:https://www.jianshu.com/p/f70... AOP設(shè)計(jì)模式通常運(yùn)用在日志,校驗(yàn)等業(yè)務(wù)場景,本文將簡單介紹基于Spring的AOP代理模式的運(yùn)用。 1. 代理模...
閱讀 2932·2021-11-23 09:51
閱讀 3105·2021-11-15 11:39
閱讀 2987·2021-11-09 09:47
閱讀 2537·2019-08-30 13:49
閱讀 2118·2019-08-30 13:09
閱讀 3103·2019-08-29 16:10
閱讀 3510·2019-08-26 17:04
閱讀 997·2019-08-26 13:57