Spring框架_靜態(tài)代理 動態(tài)代理

什么是代理

我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委托”代理為其銷售商品。關(guān)于微商代理,首先我們從他們那里買東西時通常不知道背后的廠家究竟是誰,也就是說,“委托者”對我們來說是不可見的;我們把微商代理和廠家進一步抽象,前者可抽象為代理類,后者可抽象為委托類(被代理類)。通過使用代理,通常有兩個優(yōu)點,并且能夠分別與我們提到的微商代理的兩個特點對應(yīng)起來:
優(yōu)點一:可以隱藏委托類的實現(xiàn);
優(yōu)點二:可以實現(xiàn)客戶與委托類間的解耦,在不修改委托類代碼的情況下能夠做一些額外的處理。

靜態(tài)代理

由程序員創(chuàng)建或工具生成代理類的源碼,再編譯代理類。所謂靜態(tài)也就是在程序運行前就已經(jīng)存在代理類的字節(jié)碼文件,代理類和委托類的關(guān)系在運行前就確定了。若代理類在程序運行前就已經(jīng)存在,那么這種代理方式被成為 靜態(tài)代理 ,這種情況下的代理類通常都是我們在Java代碼中定義的。 通常情況下, 靜態(tài)代理中的代理類和委托類會實現(xiàn)同一接口或是派生自相同的父類。 下面我們用Vendor類代表生產(chǎn)廠家,Business類代表微商代理,來介紹下靜態(tài)代理的簡單實現(xiàn),委托類和代理類都實現(xiàn)了Sell接口.:

//接口
public interface Sell {
  void sell();
  
}
public class Business implements Sell{

    public void sell() {
        System.out.println("代理買東西");
        
    }

}
public class Vendor implements Sell{

    public void sell() {
        System.out.println("廠家買東西");
        
    }
   
}
public class Test {
    
    public static void main(String[] args) {
        Sell s=new Vendor();
        s.sell();
    }

}

測試結(jié)果:廠家買東西

靜態(tài)代理類優(yōu)缺點

優(yōu)點:業(yè)務(wù)類只需要關(guān)注業(yè)務(wù)邏輯本身,保證了業(yè)務(wù)類的重用性。這是代理的共有優(yōu)點。
缺點:
1)代理對象的一個接口只服務(wù)于一種類型的對象,如果要代理的方法很多,勢必要為每一種方法都進行代理,靜態(tài)代理在程序規(guī)模稍大時就無法勝任了。
2)如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。增加了代碼維護的復(fù)雜度。

動態(tài)代理

代理類在程序運行時創(chuàng)建的代理方式被成為 動態(tài)代理。 也就是說,這種情況下,代理類并不是在Java代碼中定義的,而是在運行時根據(jù)我們在Java代碼中的“指示”動態(tài)生成的。相比于靜態(tài)代理, 動態(tài)代理的優(yōu)勢在于可以很方便的對代理類的函數(shù)進行統(tǒng)一的處理,而不用修改每個代理類的函數(shù)。 這么說比較抽象,下面我們結(jié)合一個實例來介紹一下動態(tài)代理的這個優(yōu)勢是怎么體現(xiàn)的

//代理商
public class Business implements InvocationHandler{

    //指示
    private Object obj;
    
    
//  public void sell() {
//      System.out.println("代理買東西");
//      
//  }

    public Object getObj() {
        return obj;
    }


    public void setObj(Object obj) {
        this.obj = obj;
    }


    public Business(Object obj) {
        super();
        this.obj = obj;
    }


    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        method.invoke(obj, args);
        //System.out.println("代理買東西");
        return obj;
    }

}

測試

public class Test {
    
    public static void main(String[] args) {
        
        Business b=new Business(new Vendor());
        Sell s=(Sell)Proxy.newProxyInstance(Vendor.class.getClassLoader(), Vendor.class.getInterfaces(), b);
        s.sell();
    }

}

測試結(jié)果:廠家買東西

動態(tài)代理實現(xiàn)步驟

具體步驟是:
a. 實現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器
b. 給Proxy類提供ClassLoader和代理接口類型數(shù)組創(chuàng)建動態(tài)代理類
c. 以調(diào)用處理器類型為參數(shù),利用反射機制得到動態(tài)代理類的構(gòu)造函數(shù)
d. 以調(diào)用處理器對象為參數(shù),利用動態(tài)代理類的構(gòu)造函數(shù)創(chuàng)建動態(tài)代理類對象

動態(tài)代理的優(yōu)點

優(yōu)點:
動態(tài)代理與靜態(tài)代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個集中的方法中處理(InvocationHandler.invoke)。這樣,在接口方法數(shù)量比較多的時候,我們可以進行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進行中轉(zhuǎn)。

推介:
http://doushini.iteye.com/blog/1847913
http://www.jb51.net/article/95685.htm

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 1、代理概念 為某個對象提供一個代理,以控制對這個對象的訪問。 代理類和委托類有共同的父類或父接口,這樣在任何使用...
    孔垂云閱讀 7,752評論 4 54
  • 一、代理概念 為某個對象提供一個代理,以控制對這個對象的訪問。 代理類和委托類有共同的父類或父接口,這樣在任何使用...
    wyatt_plus閱讀 803評論 0 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,881評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,759評論 18 399
  • 黑執(zhí)事·那個執(zhí)事,真愛【同人/耽美/不喜勿入】 入黑執(zhí)事的坑已經(jīng)四年了,很喜歡塞夏這對別扭的主仆,今天我們來講述他...
    秦云渚閱讀 420評論 0 2