靜態代理
靜態代理相對來說比較簡單,無非就是聚合+多態:
參考:設計模式筆記 – Proxy 代理模式 (Design Pattern)
動態代理
我們知道,通過使用代理,可以在被代理的類的方法的前后添加一些處理方法,這樣就達到了類似AOP的效果。而JDK中提供的動態代理,就是實現AOP的絕好底層技術。
JDK動態代理
JDK動態代理主要涉及到java.lang.reflect包中的兩個類:Proxy和InvocationHandler。InvocationHandler是一個接口,通過實現該接口定義橫切邏輯,并通過反射機制調用目標類的代碼,動態將橫切邏輯和業務邏輯編制在一起。
Proxy利用InvocationHandler動態創建一個符合某一接口的實例,生成目標類的代理對象。
例子:Java筆記 – 反射 動態代理
CGLib動態代理
還有一個叫CGLib的動態代理,CGLib全稱為Code Generation Library,是一個強大的高性能,高質量的代碼生成類庫,可以在運行期擴展Java類與實現Java接口,CGLib封裝了asm,可以再運行期動態生成新的class。和JDK動態代理相比較:JDK創建代理有一個限制,就是只能為接口創建代理實例,而對于沒有通過接口定義業務方法的類,則可以通過CGLib創建動態代理。
CGLib采用非常底層的字節碼技術,可以為一個類創建子類,并在子類中采用方法攔截的技術攔截所有父類方法的調用,并順勢織入橫切邏輯。
JDK動態代理和CGLib的比較
CGLib所創建的動態代理對象的性能比JDK所創建的代理對象性能高不少,大概10倍,但CGLib在創建代理對象時所花費的時間卻比JDK動態代理多大概8倍,所以對于singleton的代理對象或者具有實例池的代理,因為無需頻繁的創建新的實例,所以比較適合CGLib動態代理技術,反之則適用于JDK動態代理技術。另外,由于CGLib采用動態創建子類的方式生成代理對象,所以不能對目標類中的final,private等方法進行處理。所以,大家需要根據實際的情況選擇使用什么樣的代理了。
同樣的,Spring的AOP編程中相關的ProxyFactory代理工廠內部就是使用JDK動態代理或CGLib動態代理的,通過動態代理,將增強(advice)應用到目標類中。
JDK動態代理主要用到java.lang.reflect包中的兩個類:Proxy和InvocationHandler.
InvocationHandler是一個接口,通過實現該接口定義橫切邏輯,并通過反射機制調用目標類的代碼,動態的將橫切邏輯和業務邏輯編織在一起。
Proxy利用InvocationHandler動態創建一個符合某一接口的實例,生成目標類的代理對象。