真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么理解Java動(dòng)態(tài)代理機(jī)制

本篇內(nèi)容介紹了“怎么理解Java動(dòng)態(tài)代理機(jī)制”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括北海街道網(wǎng)站建設(shè)、北海街道網(wǎng)站制作、北海街道網(wǎng)頁制作以及北海街道網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,北海街道網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到北海街道省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

在java的動(dòng)態(tài)代理機(jī)制中,有兩個(gè)重要的類或接口,一個(gè)是 InvocationHandler(Interface)、另一個(gè)則是 Proxy(Class),這一個(gè)類和接口是實(shí)現(xiàn)我們動(dòng)態(tài)代理所必須用到的。首先我們先來看看java的API幫助文檔是怎么樣對(duì)這兩個(gè)類進(jìn)行描述的:

InvocationHandler:

1InvocationHandler is the interface implemented by the invocation handler of a proxy instance.2 3Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

每一個(gè)動(dòng)態(tài)代理類都必須要實(shí)現(xiàn)InvocationHandler這個(gè)接口,并且每個(gè)代理類的實(shí)例都關(guān)聯(lián)到了一個(gè)handler,當(dāng)我們通過代理對(duì)象調(diào)用一個(gè)方法的時(shí)候,這個(gè)方法的調(diào)用就會(huì)被轉(zhuǎn)發(fā)為由InvocationHandler這個(gè)接口的 invoke 方法來進(jìn)行調(diào)用。我們來看看InvocationHandler這個(gè)接口的唯一一個(gè)方法 invoke 方法:

1Object invoke(Object proxy, Method method, Object[] args) throws Throwable

我們看到這個(gè)方法一共接受三個(gè)參數(shù),那么這三個(gè)參數(shù)分別代表什么呢?

· proxy:  指代我們所代理的那個(gè)真實(shí)對(duì)象

· method:  指代的是我們所要調(diào)用真實(shí)對(duì)象的某個(gè)方法的Method對(duì)象

· args:  指代的是調(diào)用真實(shí)對(duì)象某個(gè)方法時(shí)接受的參數(shù)

如果不是很明白,等下通過一個(gè)實(shí)例會(huì)對(duì)這幾個(gè)參數(shù)進(jìn)行更深的講解。

接下來我們來看看Proxy這個(gè)類:

1Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.

Proxy這個(gè)類的作用就是用來動(dòng)態(tài)創(chuàng)建一個(gè)代理對(duì)象的類,它提供了許多的方法,但是我們用的最多的就是 newProxyInstance 這個(gè)方法:

1public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException

1Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.

這個(gè)方法的作用就是得到一個(gè)動(dòng)態(tài)的代理對(duì)象,其接收三個(gè)參數(shù),我們來看看這三個(gè)參數(shù)所代表的含義:

· loader:一個(gè)ClassLoader對(duì)象,定義了由哪個(gè)ClassLoader對(duì)象來對(duì)生成的代理對(duì)象進(jìn)行加載

· interfaces:一個(gè)Interface對(duì)象的數(shù)組,表示的是我將要給我需要代理的對(duì)象提供一組什么接口,如果我提供了一組接口給它,那么這個(gè)代理對(duì)象就宣稱實(shí)現(xiàn)了該接口(多態(tài)),這樣我就能調(diào)用這組接口中的方法了

· h:一個(gè)InvocationHandler對(duì)象,表示的是當(dāng)我這個(gè)動(dòng)態(tài)代理對(duì)象在調(diào)用方法的時(shí)候,會(huì)關(guān)聯(lián)到哪一個(gè)InvocationHandler對(duì)象上

好了,在介紹完這兩個(gè)接口(類)以后,我們來通過一個(gè)實(shí)例來看看我們的動(dòng)態(tài)代理模式是什么樣的:

首先我們定義了一個(gè)Subject類型的接口,為其聲明了兩個(gè)方法:

1public interface Subject2{3 public void rent();4 5 public void hello(String str);6}

接著,定義了一個(gè)類來實(shí)現(xiàn)這個(gè)接口,這個(gè)類就是我們的真實(shí)對(duì)象,RealSubject類:

01public class RealSubject implements Subject02{03 @Override04 public void rent()05 {06 System.out.println("I want to rent my house");07 }08 09 @Override10 public void hello(String str)11 {12 System.out.println("hello: " + str);13 }14}

下一步,我們就要定義一個(gè)動(dòng)態(tài)代理類了,前面說個(gè),每一個(gè)動(dòng)態(tài)代理類都必須要實(shí)現(xiàn) InvocationHandler 這個(gè)接口,因此我們這個(gè)動(dòng)態(tài)代理類也不例外:

01public class DynamicProxy implements InvocationHandler02{03 // 這個(gè)就是我們要代理的真實(shí)對(duì)象04 private Object subject;05 06 // 構(gòu)造方法,給我們要代理的真實(shí)對(duì)象賦初值07 public DynamicProxy(Object subject)08 {09 this.subject = subject;10 }11 12 @Override13 public Object invoke(Object object, Method method, Object[] args)14 throws Throwable15 {16 //  在代理真實(shí)對(duì)象前我們可以添加一些自己的操作17 System.out.println("before rent house");18 19 System.out.println("Method:" + method);20 21 // 當(dāng)代理對(duì)象調(diào)用真實(shí)對(duì)象的方法時(shí),其會(huì)自動(dòng)的跳轉(zhuǎn)到代理對(duì)象關(guān)聯(lián)的handler對(duì)象的invoke方法來進(jìn)行調(diào)用22 method.invoke(subject, args);23 24 //  在代理真實(shí)對(duì)象后我們也可以添加一些自己的操作25 System.out.println("after rent house");26 27 return null;28 }29 30}

最后,來看看我們的Client類:

01public class Client02{03 public static void main(String[] args)04 {05 // 我們要代理的真實(shí)對(duì)象06 Subject realSubject = new RealSubject();07 08 // 我們要代理哪個(gè)真實(shí)對(duì)象,就將該對(duì)象傳進(jìn)去,最后是通過該真實(shí)對(duì)象來調(diào)用其方法的09 InvocationHandler handler = new DynamicProxy(realSubject);10 11 /*12 * 通過Proxy的newProxyInstance方法來創(chuàng)建我們的代理對(duì)象,我們來看看其三個(gè)參數(shù)13 * 第一個(gè)參數(shù) handler.getClass().getClassLoader() ,我們這里使用handler這個(gè)類的ClassLoader對(duì)象來加載我們的代理對(duì)象14 * 第二個(gè)參數(shù)realSubject.getClass().getInterfaces(),我們這里為代理對(duì)象提供的接口是真實(shí)對(duì)象所實(shí)行的接口,表示我要代理的是該真實(shí)對(duì)象,這樣我就能調(diào)用這組接口中的方法了15 * 第三個(gè)參數(shù)handler, 我們這里將這個(gè)代理對(duì)象關(guān)聯(lián)到了上方的 InvocationHandler 這個(gè)對(duì)象上16 */17 Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject18 .getClass().getInterfaces(), handler);19 20 System.out.println(subject.getClass().getName());21 subject.rent();22 subject.hello("world");23 }24}

我們先來看看控制臺(tái)的輸出:

01$Proxy002 03before rent house04Method:public abstract void com.xiaoluo.dynamicproxy.Subject.rent()05I want to rent my house06after rent house07 08before rent house09Method:public abstractvoidcom.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)10hello: world11after rent house

我們首先來看看 $Proxy0 這東西,我們看到,這個(gè)東西是由 System.out.println(subject.getClass().getName()); 這條語句打印出來的,那么為什么我們返回的這個(gè)代理對(duì)象的類名是這樣的呢?

1Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject2 .getClass().getInterfaces(), handler);

可能我以為返回的這個(gè)代理對(duì)象會(huì)是Subject類型的對(duì)象,或者是InvocationHandler的對(duì)象,結(jié)果卻不是,首先我們解釋一下為什么我們這里可以將其轉(zhuǎn)化為Subject類型的對(duì)象?原因就是在newProxyInstance這個(gè)方法的第二個(gè)參數(shù)上,我們給這個(gè)代理對(duì)象提供了一組什么接口,那么我這個(gè)代理對(duì)象就會(huì)實(shí)現(xiàn)了這組接口,這個(gè)時(shí)候我們當(dāng)然可以將這個(gè)代理對(duì)象強(qiáng)制類型轉(zhuǎn)化為這組接口中的任意一個(gè),因?yàn)檫@里的接口是Subject類型,所以就可以將其轉(zhuǎn)化為Subject類型了。

同時(shí)我們一定要記住,通過 Proxy.newProxyInstance 創(chuàng)建的代理對(duì)象是在jvm運(yùn)行時(shí)動(dòng)態(tài)生成的一個(gè)對(duì)象,它并不是我們的InvocationHandler類型,也不是我們定義的那組接口的類型,而是在運(yùn)行是動(dòng)態(tài)生成的一個(gè)對(duì)象,并且命名方式都是這樣的形式,以$開頭,proxy為中,最后一個(gè)數(shù)字表示對(duì)象的標(biāo)號(hào)。

接著我們來看看這兩句

subject.rent();subject.hello(“world”);

這里是通過代理對(duì)象來調(diào)用實(shí)現(xiàn)的那種接口中的方法,這個(gè)時(shí)候程序就會(huì)跳轉(zhuǎn)到由這個(gè)代理對(duì)象關(guān)聯(lián)到的 handler 中的invoke方法去執(zhí)行,而我們的這個(gè) handler 對(duì)象又接受了一個(gè) RealSubject類型的參數(shù),表示我要代理的就是這個(gè)真實(shí)對(duì)象,所以此時(shí)就會(huì)調(diào)用 handler 中的invoke方法去執(zhí)行:

01public Object invoke(Object object, Method method, Object[] args)02 throws Throwable03 {04 //  在代理真實(shí)對(duì)象前我們可以添加一些自己的操作05 System.out.println("before rent house");06 07 System.out.println("Method:" + method);08 09 // 當(dāng)代理對(duì)象調(diào)用真實(shí)對(duì)象的方法時(shí),其會(huì)自動(dòng)的跳轉(zhuǎn)到代理對(duì)象關(guān)聯(lián)的handler對(duì)象的invoke方法來進(jìn)行調(diào)用10 method.invoke(subject, args);11 12 //  在代理真實(shí)對(duì)象后我們也可以添加一些自己的操作13 System.out.println("after rent house");14 15 return null;16 }

我們看到,在真正通過代理對(duì)象來調(diào)用真實(shí)對(duì)象的方法的時(shí)候,我們可以在該方法前后添加自己的一些操作,同時(shí)我們看到我們的這個(gè) method 對(duì)象是這樣的:

1public abstract void com.xiaoluo.dynamicproxy.Subject.rent()2 3public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)

正好就是我們的Subject接口中的兩個(gè)方法,這也就證明了當(dāng)我通過代理對(duì)象來調(diào)用方法的時(shí)候,起實(shí)際就是委托由其關(guān)聯(lián)到的 handler 對(duì)象的invoke方法中來調(diào)用,并不是自己來真實(shí)調(diào)用,而是通過代理的方式來調(diào)用的。

“怎么理解Java動(dòng)態(tài)代理機(jī)制”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


名稱欄目:怎么理解Java動(dòng)態(tài)代理機(jī)制
當(dāng)前路徑:http://weahome.cn/article/pcjgji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部