1. 程式人生 > >淺談代理 模式與java中的動態代理

淺談代理 模式與java中的動態代理

特殊 加工 依賴 mage 應用 主題 額外 我們 動態代理

代理模式的定義:

代理模式是一個使用律非常高的模式,定義如下:
為其他對象提供一種代理,以控制對這個對象的訪問。
類圖:技術分享圖片

簡單的靜態代理:

public interface IRunner{
    //這是一個代理類和被代理類都需要實現的接口
    //在接口中定義一個抽象函數
    public void request();
}

//下面是真實的被代理類
public class Runner implements IRunner{
//實現接口中的方法
    public void request(){
    //實現具體的業務邏輯
    }
}
//下面是代理類
public class RunnerAgent implements IRunner{
    //要代理哪個實現類
    private IRunner runner  = null;
    //默認被代理者
    public RunnerAgent(IRunner runner){
        this.runner = runner;
    }
    //實現接口中定義的方法
    public void request(){
        this.before();
        this.runner.request();
        this.after();
    }
    //預處理
    private void before(){
    }
    //後處理
    private void after(){
    }

}
  • 我們可以看到靜態代理只能代理某一個類,每個類都有一個代理類。在對通用性要求更高的場景下(比如Spring AOP)傳統的靜態代理不能滿足需求,會使類的數目非常龐大,因此又有了動態代理。

    動態代理

    什麽是動態代理?動態代理就是在實現階段不用關心代理誰,而在運行階段才指定代理哪一個對象。動態代理的一個重要應用就是面向切面編程(AOP)
    AOP示意圖:
    技術分享圖片

通過示意圖可以明顯的看出來,AOP抽取出非業務邏輯代碼,降低了耦合度。
動態代理的通用類圖(jdk動態代理,如無特殊聲明,以下動態代理均指jdk動態代理)
技術分享圖片

  • jdk動態代理 vs cglib動態代理
    jdk動態代理是以接口為中心的,相當於添加類一種對於被調用者沒有太大意義的限制。我們實例化的是代理對象,而不是真正被調用的類型,這在實踐中可能帶來不便。
    如果被調用者沒有實現接口,而我們還是希望利用動態代理機制,那麽可以考慮其他方式。我們知道Spring AOP支持兩種模式的動態代理:jdk動態代理和cglib。如果我們選擇cglib方式,就不再依賴接口。
    cglib動態代理采取的方式是創建被代理類的子類。因此要求被代理類不可以用final修飾。
    jdk動態代理的優勢:
    最小化依賴關系
    代碼實現簡單。
    cglib代理優勢:
    不需要被代理類實現額外接口。
    只操作我們關心的類,而不必為其他相關類增加工作量。
    高性能。

    代理模式的優點

  • 職責清晰
    真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過後期的代理完成一件事務,附帶的結果就是編程簡潔清晰。
  • 高擴展性
    具體主題角色是隨時都會發生變化的。只要實現了接口,不管如何變化,都離不開接口的規範,那我們的代理類完全就可以在不做任何修改的情況下使用。

參考文獻:設計模式之禪 秦小波 著

淺談代理 模式與java中的動態代理