代理模式之靜態代理和動態代理

靜態代理

靜態代理是由程序員創建或工具生成代理類的源碼,再編譯代理類。

所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委託類的關係在運行前就確定了。

(1)基於接口實現方式

 

(2)接口繼承方式實現

public class OrderServiceProxy extends OrderServiceImpl {

    public void order() {
        System.out.println("前置通知..");
        super.order();
        System.out.println("後置通知..");
    }
}

public class ClientTest {
    public static void main(String[] args) {
        OrderService orderService = new OrderServiceProxy();
        orderService.order();
    }
}

動態代理

動態代理是在實現階段不用關心代理類,而在運行階段才指定哪一個對象。

(1)JDK動態代理

JDK動態代理的一般步驟如下:

1.創建被代理的接口和類;

2.實現InvocationHandler接口,對目標接口中聲明的所有方法進行統一處理;

3.調用Proxy的靜態方法,創建代理類並生成相應的代理對象;

動態代理類的源碼是在程序運行期間由JVM根據反射等機制動態的生成 。

 

動態代理原理分析:

       1、創建代理類$Proxy0源代碼文件實現被代理的接口。

       2、使用JavaCompiler技術編譯該$Proxy0文件獲取到$Proxy0.class

       3、使用ClassLoader將該$Proxy0.class加入到當前JVM內存中

注意:繼承了Proxy類,實現了代理的接口,由於java不能多繼承,這裏已經繼承了Proxy類了,不能再繼承其他的類,所以JDK的動態代理不支持對實現類的代理,只支持接口的代理。

(2)CGLIB動態代理

Cglib是一個強大的,高性能,高質量的代碼生成類庫。它可以在運行期擴展JAVA類與實現JAVA接口。其底層實現是通過ASM字節碼處理框架來轉換字節碼並生成新的類。大部分功能實際上是ASM所提供的,Cglib只是封裝了ASM,簡化了ASM操作,實現了運行期生成新的class。

 

CGLIB原理

運行時動態的生成一個被代理類的子類(通過ASM字節碼處理框架實現),子類重寫了被代理類中所有非final的方法。在子類中採用方法攔截的技術攔截所有父類方法的調用,順勢植入橫切邏輯。

 

Cglib優缺點

優點:JDK動態代理要求被代理的類必須實現接口,當需要代理的類沒有實現接口時Cglib代理是一個很好的選擇。另一個優點是Cglib動態代理比使用java反射的JDK動態代理要快

缺點:對於被代理類中的final方法,無法進行代理,因爲子類中無法重寫final函數

 

CGLIB代理實現

實現MethodInterceptor接口的intercept方法後,所有生成的代理方法都調用這個方法。

intercept方法的具體參數有

obj 目標類的實例

1.      method 目標方法實例(通過反射獲取的目標方法實例)

2.      args 目標方法的參數

3.      proxy 代理類的實例

該方法的返回值就是目標方法的返回值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章