接上一篇Spring AOP系列(一)— 代理模式,本篇來聊聊動態代理,
動態代理與靜態代理的區別
要想了解動態代理與靜態代理的區別,需要有兩個前置知識點:java程式是如何執行的以及類加載機制,
java程式執行程序

- 將java原始碼(.java檔案)通過編譯器(javac.exe)編譯成JVM檔案(.class檔案),
- 將JVM檔案通過java.exe執行,輸出結果,
靜態代理顯示的撰寫了代理類,因此編譯程序中會生成對應的.class檔案,最終在運行程序中執行這些.class檔案,而動態代理并未顯示撰寫代理類,也并不存在代理類的.class檔案,而是在程式運行期間由JVM根據反射等機制動態的生成,
類加載機制
java虛擬機中類加載的全程序,分別是:加載、驗證、準備、決議、初始化,其中“加載”是類加載的第一個步驟,在加載階段,虛擬機需要完成以下3件事情:
- 通過一個類的全限定名來獲取定義此類的二進制位元組流,
- 將這個位元組流所代表的靜態存盤結構轉化為方法區的運行時資料結構,
- 在記憶體中生成一個代表這個類的
java.lang.class物件,作為方法區這個類的各種資料訪問入口,
由于虛擬機規范對這3點要求并不具體,所以實際的實作是非常靈活的,關于第1點,獲取類的二進制位元組流(class位元組碼)就有很多途徑:
- 從ZIP包獲取,這是JAR、EAR、WAR等格式的基礎,
- 從網路中獲取,典型的應用是 Applet,
- 運行時計算生成,這種場景使用最多的是動態代理技術,在
java.lang.reflect.Proxy類中,就是用了ProxyGenerator.generateProxyClass來為特定介面生成形式為*$Proxy的代理類的二進制位元組流, - 由其它檔案生成,典型應用是JSP,即由JSP檔案生成對應的Class類,
- 從資料庫中獲取等等,
其中“運行時計算生成”,就是“動態代理”技術的實作思路,
小結
靜態代理的優點
實作簡單,且不侵入原代碼,
靜態代理的缺點
- 靜態代理要求:代理物件與被代理物件需要實作一致的介面,因此當希望使用一個代理類代理多個被代理類時,可以通過以下兩種方式:
- 只維護一個代理類,由這個代理類實作多個介面,但是這樣就導致代理類過于龐大,
- 新建多個代理類,每個目標物件對應一個代理類,但是這樣會產生過多的代理類,
- 當介面需要增加、洗掉、修改方法的時候,目標物件與代理類都要同時修改,不易維護,
動態代理的優勢不在于省去了撰寫代理類的作業量,而是實作了可以在原始類和介面還未知的時候,就確定代理類的代理行為,當代理類與原始類脫離直接聯系后,就可以很靈活地重用于不同的應用場景之中,
接下來將詳細地介紹動態代理的兩種常見的實作方式:常見的動態代理的實作方式有兩種:JDK動態代理和CGLIB動態代理
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/93743.html
標籤:設計模式
上一篇:python條件控制陳述句
