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