關(guān)于動態(tài)代理

通過代碼進(jìn)行理解:

1.接口

public interface Subject {? ? ??

? ? ? ? ? public void rent();? ? ??

? ? ? ? ? public void hello(String str);

? }

2.實現(xiàn)類

public class RealSubject implements Subject{?

? ? ? ? ? @Override

? ? ? ? ? ? public void rent(){? ? ? ??

? ? ? ? ? ? ? ? ?System.out.println("I want to rent my House!");? ??

? ? ? ? ? ? }

????????????@Override

????????????????publicvoidhello(String str){

????????????? ? ? ? System.out.println("Hello:"+str);? ??

????????????}? ??

}

3.代理類

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class DynamicProxy implements InvocationHandler{

????private Object subject;//這是要代理的真實對象

? ? public Dynamic Proxy(Object subject){

????????this.subject=subject;//給要代理的真實對象初始化

????}??

????@Override

????public Object invoke(Object proxy, Method method,Object[] args)throwsThrowable {

????????//第一個參數(shù)是指最終生成的代理對象酿矢,也就是所要代理的真實對象

????????// 第二個是代理的方法,也就是所要代理的真實對象的某個方法

????????// 第三個是參數(shù)蜜暑,也就是真實對象調(diào)用的方法(第二個參數(shù))所需要的參數(shù)System.out.println("before rent house");

????????//代理前的添加的自定義操作策肝,此處是為了更好的看到代理效果????????

? ? ? ? ?System.out.println("Method:"+method);

????????//真實對象的方法

????????method.invoke(subject,args);

????????//當(dāng)代理對象調(diào)用真實對象的方法時之众,其會自動的跳轉(zhuǎn)到代理對象關(guān)聯(lián)的handler對象的invoke方法來進(jìn)行調(diào)用//個人理解就是代理對象調(diào)用真實對象的方法,就跳轉(zhuǎn)到真實對象的方法去執(zhí)行????

????????System.out.println("after rent house");//代理后的操作缀蹄,此處是為了更好的看到代理效果

????????return null;?

?????}

}

4.客戶端

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

public classClient{

????????public static void main(Stringargs[]){? ??

????????????Subject realSubject=newRealSubject();//真實對象InvocationHandler ????????????handler=newDynamicProxy(realSubject);//代理對象

????????????????//Proxy這個類的作用就是用來動態(tài)創(chuàng)建一個代理對象的類缺前,它提供了許多的方法,但是我們用的最多的就是 newProxyInstance 這個方法

????????????Subject subject= (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(),realSubject.getClass()

.getInterfaces(),handler);

? ?????????//第一個參數(shù)一個ClassLoader對象拯刁,定義了由哪個ClassLoader對象來對生成的代理對象進(jìn)行加載

????????????//第二個參數(shù)逝段,一個Interface對象的數(shù)組惹恃,表示的是我將要給我需要代理的對象提供一組什么接口,如果我提供了一組接口給它朗儒,

????????????// 那么這個代理對象就宣稱實現(xiàn)了該接口(多態(tài))参淹,這樣我就能調(diào)用這組接口中的方法了。

????????????????// 為什么能定義這個類型的對象恳不,因為我們給這個代理對象提供了一組什么接口开呐,那么我這個代理對象就會實現(xiàn)了這組接口筐付,可以轉(zhuǎn)化為接口中的任意一個類型并且必須使用接口類型//第三個參數(shù),一個InvocationHandler對象沮尿,表示的是當(dāng)我這個動態(tài)代理對象在調(diào)用方法的時候较解,會關(guān)聯(lián)到哪一個InvocationHandler對象上

????????????System.out.println(subject.getClass().getName();

/**

? ? * 可能我以為返回的這個代理對象會是Subject類型的對象,或者是InvocationHandler的對象啡捶,結(jié)果卻不是奸焙,

? ? * 首先我們解釋一下為什么我們這里可以將其轉(zhuǎn)化為Subject類型的對象徒溪?原因就是在newProxyInstance這個方法的第二個參數(shù)上臊泌,

? ? * 我們給這個代理對象提供了一組什么接口揍拆,那么我這個代理對象就會實現(xiàn)了這組接口,

? ? * 這個時候我們當(dāng)然可以將這個代理對象強(qiáng)制類型轉(zhuǎn)化為這組接口中的任意一個播揪,因為這里的接口是Subject類型筒狠,所以就可以將其轉(zhuǎn)化為Subject類型了辩恼。

? ? * 同時我們一定要記住雇庙,通過 Proxy.newProxyInstance 創(chuàng)建的代理對象是在jvm運行時動態(tài)生成的一個對象,它并不是我們的InvocationHandler類型灶伊,

? ? * 也不是我們定義的那組接口的類型疆前,而是在運行是動態(tài)生成的一個對象,并且命名方式都是這樣的形式聘萨,以$開頭竹椒,proxy為中,最后一個數(shù)字表示對象的標(biāo)號米辐。

? ? */

????????????subject.rent();? ?????????

?????????????subject.hello(" world!");

/**

? ? *正好就是我們的Subject接口中的兩個方法胸完,這也就證明了當(dāng)我通過代理對象來調(diào)用方法的時候,

? ? * 起實際就是委托由其關(guān)聯(lián)到的 handler 對象的invoke方法中來調(diào)用翘贮,并不是自己來真實調(diào)用赊窥,而是通過代理的方式來調(diào)用的。

? ? */

????????}

}

5.newProxyInstance源碼

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

????????Objects.requireNonNull(h);

????????finalClass[] intfs = interfaces.clone();

?????????SecurityManager sm = System.getSecurityManager();

????????if(sm !=null) {

????????????checkProxyAccess(Reflection.getCallerClass(), loader, intfs);

????????}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末择膝,一起剝皮案震驚了整個濱河市检激,隨后出現(xiàn)的幾起案子肴捉,更是在濱河造成了極大的恐慌,老刑警劉巖叔收,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件齿穗,死亡現(xiàn)場離奇詭異,居然都是意外死亡饺律,警方通過查閱死者的電腦和手機(jī)窃页,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脖卖,你說我怎么就攤上這事乒省。” “怎么了畦木?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵袖扛,是天一觀的道長。 經(jīng)常有香客問我十籍,道長蛆封,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任勾栗,我火速辦了婚禮惨篱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘围俘。我一直安慰自己砸讳,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布楷拳。 她就那樣靜靜地躺著绣夺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欢揖。 梳的紋絲不亂的頭發(fā)上陶耍,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音她混,去河邊找鬼烈钞。 笑死,一個胖子當(dāng)著我的面吹牛坤按,可吹牛的內(nèi)容都是我干的毯欣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼臭脓,長吁一口氣:“原來是場噩夢啊……” “哼酗钞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起来累,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤砚作,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘹锁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葫录,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年领猾,在試婚紗的時候發(fā)現(xiàn)自己被綠了米同。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骇扇。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖面粮,靈堂內(nèi)的尸體忽然破棺而出少孝,到底是詐尸還是另有隱情,我是刑警寧澤熬苍,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布韭山,位于F島的核電站,受9級特大地震影響冷溃,放射性物質(zhì)發(fā)生泄漏钱磅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一似枕、第九天 我趴在偏房一處隱蔽的房頂上張望盖淡。 院中可真熱鬧,春花似錦凿歼、人聲如沸褪迟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽味赃。三九已至,卻和暖如春虐拓,著一層夾襖步出監(jiān)牢的瞬間心俗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工蓉驹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留城榛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓态兴,卻偏偏與公主長得像狠持,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瞻润,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容