動態代理作用:功能增強和控制訪問
動態代理是指,程序在整個運行過程中根本就不存在目標類的代理類,目標對象的代理對象只是由代理生成工具(不是真實定義的類)在程序運行時由 JVM 根據反射等機制動態生成的。代理對象與目標對象的代理關系在程序運行時才確立。
對比靜態代理,靜態代理是指在程序運行前就已經定義好了目標類的代理類。代理類與目標類的代理關系在程序運行之前就確立了。
動態代理的實現方式常用的有兩種:使用 JDK 的 Proxy,與通過 CGLIB 生成代理。
Jdk 的動態要求目標對象必須實現接口,這是 java 設計上的要求。
從 jdk1.3 以來,java 語言通過 java.lang.reflect 包提供三個類支持代理模式 Proxy, Method和 InovcationHandler。
newProxyInstance(),依據目標對象、業務接口及調用處理器三者,自動生成一個動態代理對象。
public static newProxyInstance ( ClassLoaderloader, Class[]interfaces, InvocationHandlerhandler)
loader:目標類的類加載器,通過目標對象的反射可獲取
interfaces:目標類實現的接口數組,通過目標對象的反射可獲取
handler:調用處理器。
實現了 InvocationHandler 接口的類用于加強目標類的主業務邏輯。這個接口中有一個方法 invoke(),具體加強的代碼邏輯就是定義在該方法中的。程序調用主業務邏輯時,會自動調用 invoke()方法。
//Object proxy:代理對象
//Method m :調用的方法
//Object [] args: 調用方法的參數
public Object invoke(Object proxy, Method m, Object[] args)
這兩個 invoke()方法,雖然同名,但無關。
public Object invoke ( Object obj, Object... args)
obj:表示目標對象args:表示目標方法參數,就是其上一層 invoke 方法的第三個參數
CGLIB(Code Generation Library)是一個開源項目。是一個強大的,高性能,高質量的 Code生成類庫,它可以在運行期擴展 Java 類與實現 Java 接口。它廣泛的被許多 AOP 的框架使用,例如 Spring AOP。
使用 JDK 的 Proxy 實現代理,要求目標類與代理類實現相同的接口。若目標類不存在接口,則無法使用該方式實現。但對于無接口的類,要為其創建動態代理,就要使用 CGLIB來實現。
CGLIB 代理的生成原理是生成目標類的子類,而子類是增強過的,這個子類對象就是代理對象。所以,使用 CGLIB 生成動態代理,要求目標類必須能夠被繼承,即不能是 final 的類。
CGLIB 經常被應用在框架中,例如 Spring ,Hibernate 等。cglib 的代理效率高于 Jdk。
項目中直接使用動態代理的地方不多。一般都使用框架提供的功能。
SomeSerivce.java ,有 String doSome()方法