動(dòng)態(tài)代理模式

一、動(dòng)態(tài)代理類

1茉唉、Java的動(dòng)態(tài)代理類位于java.lang.reflect包下。一般主要涉及到下面兩個(gè)類:

(1) Interface InvocationHandler。該接口只定義了一個(gè)方法

 /**
   * @param proxy 該方法被調(diào)用的代理實(shí)例
   * @param method 被代理對(duì)象想要執(zhí)行的方法
   * @param args 所執(zhí)行方法的參數(shù)
  */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

(2) Proxy颠印。該類為動(dòng)態(tài)代理類纲岭,作用相當(dāng)于靜態(tài)代理中的ProxySubject。主要有下面三個(gè)方法:

//構(gòu)造函數(shù)线罕,用于給內(nèi)部的h賦值止潮。
protected Proxy(InvocationHandler h)

//獲得一個(gè)代理類,其中l(wèi)oader是類裝載器钞楼,interfaces是真實(shí)類所擁有的全部接口的數(shù)組
static Class getProxyClass (ClassLoader loader, Class[] interfaces)

//返回代理類的一個(gè)實(shí)例喇闸,返回后的代理類可以當(dāng)作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

2、Dynamic Proxy是在運(yùn)行時(shí)生成的class询件,生成它時(shí)必須提供一組接口燃乍,然后它就宣稱實(shí)現(xiàn)了這些接口,因此可以把它當(dāng)做這些接口中的任意一個(gè)來用宛琅。實(shí)際上刻蟹,這個(gè)Dynamic Proxy就是一個(gè)Proxy,它并不會(huì)完成實(shí)質(zhì)的工作嘿辟,在生成它的實(shí)例時(shí)必須提供一個(gè)InvocationHandler實(shí)例舆瘪,由它來完成實(shí)際的工作。

二红伦、demo說明

  • 各個(gè)文件介紹
//Subject.java  //抽象角色
//RealSubject.java //真實(shí)角色
//DynamicSubject.java //代理角色
//Client.java   //客戶端

1英古、 Subject.java

public interface Subject
{
    public void request();
}

2、RealSubject.java

public class RealSubject implements Subject
{
    @Override
    public void request()
    {
        System.out.println("From real Subject!");
    }
}

3昙读、DynamicSubject.java

/**
 * 動(dòng)態(tài)代理類
 * 動(dòng)態(tài)代理類必須實(shí)現(xiàn)InvocationHandler接口
 *該代理類內(nèi)部屬性是Object對(duì)象召调,實(shí)際使用時(shí)通過構(gòu)造方法傳進(jìn)一個(gè)來一個(gè)對(duì)象
 *此外,該代理類還實(shí)現(xiàn)了invoke方法蛮浑,該方法中的method.invoke就是執(zhí)行
 *被代理對(duì)象想要執(zhí)行的方法唠叛,方法參數(shù)是sub,表示該方法從屬于sub陵吸。同時(shí)我們
 *還可以在執(zhí)行真實(shí)對(duì)象的方法前后添加一些額外的方法玻墅。
 * @author Chuan
 *
 */
public class DynamicSubject implements InvocationHandler
{
    private Object sub;
    
    public DynamicSubject(Object object)
    {
        this.sub = object;
    }

    /**
     * @param proxy 該方法被調(diào)用的代理實(shí)例
     * @param method 被代理對(duì)象想要執(zhí)行的方法
     * @param args 所執(zhí)行方法的參數(shù)
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before calling: " + method);
        method.invoke(sub, args);
        System.out.println("after calling: " + method);
        return null;
    }

}

4、Client.java

public class Client
{
    public static void main(String[] args)
    {
        RealSubject realSubject = new RealSubject();
        
        InvocationHandler handler = new DynamicSubject(realSubject);
        
        /**
                 *Proxy.newProxyInstance()一次性生成代理類
         * Proxy.newProxyInstance()方法的第一個(gè)參數(shù)是代理類的裝載器
         * 第二個(gè)參數(shù)是代理類應(yīng)該實(shí)現(xiàn)的接口壮虫,即被代理類實(shí)現(xiàn)的接口
         * 第三個(gè)參數(shù) 是一個(gè)InvocationHandler
         * 
         * 最后在執(zhí)行過程中動(dòng)態(tài)生成一個(gè)$Proxy0對(duì)象澳厢,
         * $Proxy0類實(shí)現(xiàn)了Subject接口(realSubject.getClass().getInterfaces())
         */
        Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), 
                realSubject.getClass().getInterfaces(), handler);
        //代理對(duì)象調(diào)用方法,實(shí)際上是轉(zhuǎn)到動(dòng)態(tài)代理中的invoke方法囚似,并執(zhí)行
        subject.request();
        
        System.out.println(subject.getClass());
    }
}

3剩拢、動(dòng)態(tài)代理的步驟
(1)、創(chuàng)建一個(gè)實(shí)現(xiàn)了InvocationHandler接口的類饶唤,它必須實(shí)現(xiàn)invoke方法徐伐;
(2)、創(chuàng)建被代理的類以及接口募狂;
(3)办素、通過Proxy的靜態(tài)方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)創(chuàng)建一個(gè)代理角雷;
(4)、 通過代理調(diào)用方法性穿。

上一篇:靜態(tài)代理模式
下一篇:注解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勺三,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子需曾,更是在濱河造成了極大的恐慌吗坚,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呆万,死亡現(xiàn)場(chǎng)離奇詭異商源,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谋减,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門牡彻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人出爹,你說我怎么就攤上這事讨便。” “怎么了以政?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)伴找。 經(jīng)常有香客問我盈蛮,道長(zhǎng),這世上最難降的妖魔是什么技矮? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任抖誉,我火速辦了婚禮,結(jié)果婚禮上衰倦,老公的妹妹穿的比我還像新娘袒炉。我一直安慰自己,他們只是感情好樊零,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布我磁。 她就那樣靜靜地躺著,像睡著了一般驻襟。 火紅的嫁衣襯著肌膚如雪夺艰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天沉衣,我揣著相機(jī)與錄音郁副,去河邊找鬼。 笑死豌习,一個(gè)胖子當(dāng)著我的面吹牛存谎,可吹牛的內(nèi)容都是我干的拔疚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼既荚,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼稚失!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起固以,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤墩虹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后憨琳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诫钓,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年篙螟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了菌湃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遍略,死狀恐怖惧所,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绪杏,我是刑警寧澤下愈,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站蕾久,受9級(jí)特大地震影響势似,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜僧著,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一履因、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盹愚,春花似錦栅迄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至端逼,卻和暖如春朗兵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顶滩。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國打工余掖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓盐欺,卻偏偏與公主長(zhǎng)得像赁豆,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冗美,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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