1. 程式人生 > >【Java核心技術】 動態代理是基於什麼原理

【Java核心技術】 動態代理是基於什麼原理

代理模式(通過代理靜默地解決一些業務無關的問題,比如遠端、安全、事務、日誌、資源關閉……讓應用開發者可以只關心他的業務)
    靜態代理:事先寫好代理類,可以手工編寫,也可以用工具生成。缺點是每個業務類都要對應一個代理類,非常不靈活。
    動態代理:執行時自動生成代理物件。缺點是生成代理代理物件和呼叫代理方法都要額外花費時間。
        JDK動態代理:基於Java反射機制實現,必須要實現了介面的業務類才能用這種辦法生成代理物件。新版本也開始結合ASM機制。
        cglib動態代理:基於ASM機制實現,通過生成業務類的子類作為代理類。
Java 發射機制的常見應用:動態代理(AOP、RPC)、提供第三方開發者擴充套件能力(Servlet容器,JDBC連線)、第三方元件建立物件(DI)……

1 關於反射
反射最大的作用之一就在於我們可以不在編譯時知道某個物件的型別,而在執行時通過提供完整的”包名+類名.class”得到。注意:不是在編譯時,而是在執行時。

功能:
•在執行時能判斷任意一個物件所屬的類。
•在執行時能構造任意一個類的物件。
•在執行時判斷任意一個類所具有的成員變數和方法。
•在執行時呼叫任意一個物件的方法。
說大白話就是,利用Java反射機制我們可以載入一個執行時才得知名稱的class,獲悉其構造方法,並生成其物件實體,能對其fields設值並喚起其methods。

應用場景:
反射技術常用在各類通用框架開發中。因為為了保證框架的通用性,需要根據配置檔案載入不同的物件或類,並呼叫不同的方法,這個時候就會用到反射——執行時動態載入需要載入的物件。

特點:
由於反射會額外消耗一定的系統資源,因此如果不需要動態地建立一個物件,那麼就不需要用反射。另外,反射呼叫方法時可以忽略許可權檢查,因此可能會破壞封裝性而導致安全問題。

2 動態代理
為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在兩者之間起到中介的作用(可類比房屋中介,房東委託中介銷售房屋、簽訂合同等)。
所謂動態代理,就是實現階段不用關心代理誰,而是在執行階段才指定代理哪個一個物件(不確定性)。如果是自己寫代理類的方式就是靜態代理(確定性)。

組成要素:
(動態)代理模式主要涉及三個要素:
其一:抽象類介面
其二:被代理類(具體實現抽象介面的類)
其三:動態代理類:實際呼叫被代理類的方法和屬性的類

實現方式:
實現動態代理的方式很多,比如 JDK 自身提供的動態代理,就是主要利用了反射機制。還有其他的實現方式,比如利用位元組碼操作機制,類似 ASM、CGLIB(基於 ASM)、Javassist 等。
舉例,常可採用的JDK提供的動態代理介面InvocationHandler來實現動態代理類。其中invoke方法是該介面定義必須實現的,它完成對真實方法的呼叫。通過InvocationHandler介面,所有方法都由該Handler來進行處理,即所有被代理的方法都由InvocationHandler接管實際的處理任務。此外,我們常可以在invoke方法實現中增加自定義的邏輯實現,實現對被代理類的業務邏輯無侵入。