Spring AOP 剖析(2)

Java 平臺上 AOP 的實現機制


1. 動態代理

 

JDK1.3之後,引入了動態代理 (Dynamic Proxy)機制,可以在運行期間,爲相應的接口(Interface)動態生成對應的代

 

理對象,所以可以將橫切關注點邏輯封裝到動態代理的 InvocatioHandler 中,然後在系統運行期間,根據橫切關注點需要織

 

入的模塊位置,將橫切邏輯織入到相應的代理類中。 以動態代理類爲載體的橫切邏輯,現在當然就可以與系統的其他模塊一起

 

工作了。

 

 

缺點或是優點:所有需要織入橫切關注點邏輯的模塊類都得實現響應的接口,因爲動態代理機制只針對接口有效。

 

Spring AOP 默認情況下采用這種機制實現 AOP 機能。

 

 

2. 動態字節碼增強

 

Java虛擬機加載的 Class 文件都是符合一定規範的,所以,只要交給 Java 虛擬機運行的文件符合 Java Class 規範,

 

程序的運行就沒有問題。 通常的 class 文件都是從 Java 源代碼文件只用 Javac 編譯器編譯而成的,但是隻要符合 Java

 

class 規範,也可以使用 ASM 或者 CGLIB 等 Java 工具庫,在程序運行期間,動態構建字節碼的 class 文件

 

 

 

在這樣的前提下,可以爲需要織入橫切邏輯的模塊類在運行期間,通過字節碼增強技術,爲這些系統系統模塊類生成

 

相應的子類,而將橫切邏輯加到這些子類中,讓應用程序在執行期間使用的是這些動態生成的子類,從而達到將橫切邏輯

 

織入系統的目的。

 

 

優點:即使模塊類沒有實現相應的接口,依然可以對其進行擴展,而不用像動態代理那樣受限於接口。


缺點:如果需要擴展的類以及類中的實例方法聲明爲 final ,則無法對其進行子類化擴展

 

Spring AOP 在無法採用動態代理機制進行 AOP 功能擴展的時候,會使用 CGLIB 庫的動態字節碼增強支持來實現 AOP 的功能擴展

 


3.  Java 代碼生成  (早期 EJB 使用,現在已經退休了)

 

大概就是 EJB 容器根據部署描述符文件提供的織入信息,會爲相應的功能模塊類生成對應的 Java 代碼,然後通過部署工具編譯 Java 代碼生成相應的 Java 類。之後,部署到 EJB 容器的功能模塊就可以正常工作了。

 

 

4. 自定義類加載器

 

所有的 Java 程序的 class 都要通過相應的 類加載器 (Classloader)加載到 Java 虛擬機之後纔可以運行。默認的

 

類加載器會讀取 class 字節碼文件,然後按照 class 字節碼規範,解析並加載這些 class 文件到虛擬機運行。如果能夠在

 

這個 class 文件加載到虛擬機運行期間,將橫切邏輯織入到 class 文件的話,就可以完成 AOP 與 OOP 的融合了。

 

 

可以通過自定義類加載器的方式完成橫切邏輯到系統的織入,自定義類加載器通過讀取外部文件規定的織入規則和必要

 

信息,在加載 class 文件期間就可以將橫切邏輯添加到系統模塊的現有邏輯中,然後將改動後的 class 交給 Java 虛擬機

 

運行。

 

優點: 可以對大部分類以及相應的實例進行織入,功能與之前的集中方式相比當然強大很多。


缺點: 最大的問題就是 類加載器 本身的使用。某些應用服務器會控制整個類加載體系,所以,在這樣的場景下使用可能會造成一定的問題。

 

 

JBoss AOP 和 AspectWerkz 框架都是採用自定義類加載器的方式實現, Spring AOP  未採用該方式。

 


5. AOL 擴展

 

AOL 擴展是最強大,也最難掌握的一種方式,,AspectJ 就屬於這種方式。AOP的各種概念在 AOL 中大都有一一對應的

 

實體。 可以使用擴展過的 AOL, 實現任何 AOP 概念實體甚至 OOP 概念實體, 比如 Aspect 以及 Class。 所有的

 

AOP 概念在 AOL 中得到了最完美的表達。

 

缺點: 該方式強大的代價就是,需要重新學習一門擴展了舊有語言的 AOL 或者全新的 AOL 語言。

 

S pring AOP 未採用該方式

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章