摘要:動(dòng)態(tài)代理是包提供的方式,它必須借助一個(gè)接口才能產(chǎn)生代理對(duì)象,所以要預(yù)先定義接口。第步,建立代理對(duì)象和真實(shí)對(duì)象的關(guān)系。第個(gè)是把生成的動(dòng)態(tài)代理對(duì)象下掛在哪些接口下,這個(gè)寫(xiě)法就是放在實(shí)現(xiàn)的接口下。
JDK動(dòng)態(tài)代理是java.lang.reflect.*包提供的方式,它必須借助一個(gè)接口才能產(chǎn)生代理對(duì)象,所以要預(yù)先定義接口。1. 接口
public interface Hello { public void sayHello() ; }2. 實(shí)現(xiàn)接口
??提供實(shí)現(xiàn)類HelloImpl來(lái)實(shí)現(xiàn)接口:
public class HelloImpl implements Hello { @Override public void sayHello() { System.out.println("Hello world!"); } }3. 動(dòng)態(tài)代理綁定
public class JdkProxyExample implements InvocationHandler { private Object target = null; /** * 建立代理對(duì)象和真是對(duì)象的代理關(guān)系,并返回代理對(duì)象 * @param obj 真實(shí)對(duì)象 * @return 代理對(duì)象 */ public Object bind(Object obj) { this.target = obj; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /** * 代理方法邏輯 * @param proxy 代理對(duì)象 * @param method 當(dāng)前的調(diào)度方法 * @param args 方法參數(shù) * @return 代理結(jié)果返回 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("進(jìn)入代理邏輯對(duì)象"); System.out.println("在調(diào)度真實(shí)對(duì)象之前的服務(wù)"); Object obj = method.invoke(target, args); System.out.println("在調(diào)度真實(shí)對(duì)象之后的服務(wù)"); return obj; } }
??在 JDK 動(dòng)態(tài)代理中,要實(shí)現(xiàn)代理邏輯類必須去實(shí)現(xiàn) java.lang.reflect.InvocationHandler接口,它里面定義了一個(gè)invoke方法,并提供接口數(shù)組用于下掛代理對(duì)象。要建立起代理對(duì)象和真實(shí)服務(wù)對(duì)象的關(guān)系,然后實(shí)現(xiàn)代理邏輯,所以一共分為兩個(gè)步驟 。
??第1步,建立代理對(duì)象和真實(shí)對(duì)象的關(guān)系。這里是使用了 bind 方法去完成的 ,方法里面首先用類的屬性 target 保存了真實(shí)對(duì)象 , 然后通過(guò)如下代碼建立并生成代理對(duì)象。
Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
??其中newProxyInstance 方法包含 3 個(gè)參數(shù)。
第 1 個(gè)是類加載器,我們采用了 target 本身的類加載器 。
第 2 個(gè)是把生成的動(dòng)態(tài)代理對(duì)象下掛在哪些接口下 ,這個(gè)寫(xiě)法就是放在 target 實(shí)現(xiàn)的接口下。 HelloWorldlmpl 對(duì)象的接口顯然就是 HelloWorld,代理對(duì)象可以這樣聲明: Hello proxy = xxxx 。
第 3 個(gè)是定義實(shí)現(xiàn)方法邏輯的代理類, this 表示當(dāng)前對(duì)象,它必須實(shí)現(xiàn)InvocationHandler 接口的 invoke 方法 ,它就是代理邏輯方法的現(xiàn)實(shí)方法。
??第2步,實(shí)現(xiàn)代理邏輯方法。 invoke 方法可 以實(shí)現(xiàn)代理邏輯, invoke 方法的 3 個(gè)參數(shù)的含義如下所示。
proxy,代理對(duì)象,就是 bind 方法生成的對(duì)象。
method , 當(dāng)前調(diào)度的方法。
args , 調(diào)度方法的參數(shù)。
4. 測(cè)試動(dòng)態(tài)代理public void testJdkProxy() { JdkProxyExample jdk =new JdkProxyExample(); //綁定關(guān)系,因?yàn)閽煸诮涌?Hello下,所以聲明代理對(duì)象 Hello proxy Hello proxy= (Hello)jdk.bind(new HelloImpl()); //注意,此時(shí)Hello對(duì)象己經(jīng)是一個(gè)代理對(duì)象,它會(huì)進(jìn)入代理的邏輯方法 invoke 里 proxy.sayHelloWorld(); }
測(cè)試結(jié)果:
進(jìn)入代理邏輯對(duì)象 在調(diào)度真實(shí)對(duì)象之前的服務(wù) Hello world! 在調(diào)度真實(shí)對(duì)象之后的服務(wù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73581.html
摘要:要明白,動(dòng)態(tài)代理類的存在意義是為了攔截方法并修改邏輯而動(dòng)態(tài)代理的局限性之一就是只能攔截接口所聲明的方法。因?yàn)閯?dòng)態(tài)代理類是繼承自業(yè)務(wù)類,所以該類和方法不能聲明成無(wú)法繼承或重寫(xiě)。者最終都是生成了一個(gè)新的動(dòng)態(tài)代理類對(duì)象。 動(dòng)態(tài)代理 1、先談靜態(tài)代理 對(duì)于靜態(tài)代理,我們已經(jīng)很熟悉了。我們擁有一個(gè)抽象類,真實(shí)類繼承自抽象類并重寫(xiě)其業(yè)務(wù)方法,代理類持有真實(shí)類的對(duì)象實(shí)例,在重寫(xiě)業(yè)務(wù)方法中通過(guò)調(diào)用真實(shí)...
摘要:動(dòng)態(tài)代理的核心是接口和類。以上結(jié)果說(shuō)明它生成的代理類為,說(shuō)明是代理。測(cè)試前提實(shí)現(xiàn)接口測(cè)試類使用接口方式注入代理方式必須以接口方式注入測(cè)試配置為,運(yùn)行結(jié)果如下實(shí)際校驗(yàn)邏輯。。。。 本文也同步發(fā)布至簡(jiǎn)書(shū),地址:https://www.jianshu.com/p/f70... AOP設(shè)計(jì)模式通常運(yùn)用在日志,校驗(yàn)等業(yè)務(wù)場(chǎng)景,本文將簡(jiǎn)單介紹基于Spring的AOP代理模式的運(yùn)用。 1. 代理模...
摘要:與靜態(tài)代理對(duì)比,動(dòng)態(tài)代理是在動(dòng)態(tài)生成代理類,由代理類完成對(duì)具體方法的封裝,實(shí)現(xiàn)的功能。本文將分析中兩種動(dòng)態(tài)代理的實(shí)現(xiàn)方式,和,比較它們的異同。那如何動(dòng)態(tài)編譯呢你可以使用,這是一個(gè)封裝了的庫(kù),幫助你方便地實(shí)現(xiàn)動(dòng)態(tài)編譯源代碼。 發(fā)現(xiàn)Java面試很喜歡問(wèn)Spring AOP怎么實(shí)現(xiàn)的之類的問(wèn)題,所以寫(xiě)一篇文章來(lái)整理一下。關(guān)于AOP和代理模式的概念這里并不做贅述,而是直奔主題,即AOP的實(shí)現(xiàn)方...
摘要:值得一提的是由于采用動(dòng)態(tài)創(chuàng)建子類的方式生成代理對(duì)象,所以不能對(duì)目標(biāo)類中的方法進(jìn)行代理。動(dòng)態(tài)代理中生成的代理類是子類,調(diào)試的時(shí)候可以看到,打開(kāi)源碼可看到實(shí)現(xiàn)了和也就實(shí)現(xiàn)方法。 前面講到了動(dòng)態(tài)代理的底層原理,接下來(lái)我們來(lái)看一下aop的動(dòng)態(tài)代理.Spring AOP使用了兩種代理機(jī)制:一種是基于JDK的動(dòng)態(tài)代理,一種是基于CGLib的動(dòng)態(tài)代理. ①JDK動(dòng)態(tài)代理:使用JDK創(chuàng)建代理有一個(gè)限制...
摘要:實(shí)際開(kāi)發(fā)中的,通用異常處理,通用日志處理,事物處理都可以用到動(dòng)態(tài)代理。四總結(jié)優(yōu)點(diǎn)動(dòng)態(tài)代理類簡(jiǎn)化了代碼編程工作,提高了軟件的可擴(kuò)展性。 JDK的動(dòng)態(tài)代理 一、靜態(tài)代理 了解動(dòng)態(tài)代理前,有必要先講解下靜態(tài)代理。 舉個(gè)例子:銀行開(kāi)通了短信業(yè)務(wù),在你取錢,存錢,轉(zhuǎn)賬后都會(huì) 給你發(fā)送短信,我們來(lái)模擬下業(yè)務(wù)場(chǎng)景。 靜態(tài)代理的實(shí)現(xiàn) 下面來(lái)模擬下業(yè)務(wù)代碼 1.定義IBankCardService接口 ...
閱讀 2323·2023-04-26 00:28
閱讀 3067·2019-08-30 15:55
閱讀 2742·2019-08-30 12:47
閱讀 1550·2019-08-29 11:04
閱讀 3150·2019-08-28 18:14
閱讀 945·2019-08-28 18:11
閱讀 1671·2019-08-26 18:36
閱讀 3383·2019-08-23 18:21