原文地址:http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml 英文地址:http://www-128.ibm.com/developerworks/java/library/j-aopwork2/ AOP@Work: AOP 工具比較,第 2 部分 |
![]() |
![]() |
![]() | |
![]() | ||||
![]() |
![]() |
開發(fā)環(huán)境
在這個(gè)由兩部分構(gòu)成的 AOP 工具比較的第 1 部分 中,介紹了 4 種領(lǐng)先的 AOP 工具(AspectJ、AspectWerkz、JBoss AOP、Spring AOP)實(shí)現(xiàn)核心 AOP 機(jī)制的方式。雖然這些工具已經(jīng)集中在連接點(diǎn)模型、切入點(diǎn)、通知和類型間聲明的思想上,但是每種工具在處理 AOP 語法時(shí),仍有各自明顯的優(yōu)缺點(diǎn)。正如在第 1 部分介紹的,語法的決策不僅影響方面編程時(shí)的感覺 —— 繁瑣的語法 VS 更加直接、作為代碼的切入點(diǎn) VS 注釋、通知保存在相同的源文件中 VS 本地化為 XML 中的方面配置 —— 而且還會(huì)對(duì)語義帶來差異。現(xiàn)在,這一部分將繼續(xù)探索不同技術(shù)的意義,但這次的重點(diǎn)是研究以上決策對(duì) AOP 工具在整體開發(fā)過程和開發(fā)環(huán)境中的集成有什么影響。 本文從深入研究 AspectJ 對(duì) Java? 語言擴(kuò)展的發(fā)展情況開始,重點(diǎn)查看代碼風(fēng)格在方面構(gòu)建和靜態(tài)檢查方面的優(yōu)勢(shì)和不足。然后討論每種工具的不同編譯方式,并用最新的 AWBench 測(cè)評(píng)結(jié)果說明它們對(duì)性能的影響。 在 AOP 工具比較的第 2 部分中,最重要的討論主題可能是 IDE 支持。本文將對(duì)每種工具的 IDE 支持逐個(gè)特性地進(jìn)行比較,并對(duì)兩個(gè)實(shí)際的 IDE 插件進(jìn)行看得見的比較。本文還會(huì)介紹每種工具的文檔和庫支持情況,這兩者是選擇新技術(shù)實(shí)現(xiàn)時(shí)的重要因素。 文章結(jié)尾提供了對(duì)這些工具未來發(fā)展方向的一些推測(cè),概括了每種工具的核心優(yōu)勢(shì)與不足。表 1 總結(jié)了整篇文章詳細(xì)討論的開發(fā)環(huán)境集成的一些關(guān)鍵因素。 表 1. AOP 工具比較:開發(fā)環(huán)境集成
如果讀者已經(jīng)讀過第 1 部分,那么現(xiàn)在可能正想進(jìn)行開發(fā)環(huán)境集成。 構(gòu)建方面 從構(gòu)建環(huán)境的角度看,這些技術(shù)的主要區(qū)別是:AspectJ 必須提供自己的編譯器,而其他工具可以依靠標(biāo)準(zhǔn)的 Java 編譯器。AspectJ 編譯器擴(kuò)展了 Eclipse Java 編譯器,可以脫離 Eclipse 在命令行上獨(dú)立運(yùn)行,也可以用作 Eclipse 和其他 IDE 的插件。AspectJ 編譯器對(duì) “.java” 或 “.aj” 文件中聲明的 AspectJ 和 Java 代碼進(jìn)行構(gòu)建,并生成普通的 Java 字節(jié)碼。雖然要使用新編譯器這點(diǎn)有些不足,但是這么做可以提供切入點(diǎn)的靜態(tài)檢查,而且還會(huì)帶來很大的益處。 切入點(diǎn)的靜態(tài)檢查 有了 AspectJ 編譯器,方面代碼就可以得到 Java 代碼從靜態(tài)檢查得到的全部好處。如果沒有該編譯器,那么在鍵入切入點(diǎn)表達(dá)式時(shí),必須非常小心,而且還要適應(yīng)通過執(zhí)行應(yīng)用程序找出錯(cuò)誤,因?yàn)榍腥朦c(diǎn)的表達(dá)式非常復(fù)雜,所以這很容易帶來問題。 在圖 1 中可以看到兩種工具處理切入點(diǎn)中括號(hào)錯(cuò)誤的區(qū)別。圖的上面顯示了 AspectJ 中錯(cuò)誤的出現(xiàn)方式,圖的下面顯示了 AspectWerkz 中錯(cuò)誤的出現(xiàn)方式。 圖 1. 在 AspectJ 中和在 AspectWerkz 中定位語法錯(cuò)誤的比較 AspectJ 的編譯器在鍵入代碼的時(shí)候就會(huì)主動(dòng)解析方面代碼,立即指出括號(hào)錯(cuò)誤。使用 AspectWerkz,則要到運(yùn)行時(shí)才會(huì)檢查出這個(gè)錯(cuò)誤。由此可以看到,在沒有切入點(diǎn)靜態(tài)檢查的工具中,這類語法錯(cuò)誤需要更多時(shí)間調(diào)試。但是,更常見、更費(fèi)時(shí)的問題則是因?yàn)樵谇腥朦c(diǎn)中拼寫出錯(cuò)誤類型名這類的錯(cuò)誤造成的。在沒有進(jìn)行靜態(tài)檢查的情況下,AOP 框架無法調(diào)用任何通知,因此會(huì)悄無聲息地失敗。指出錯(cuò)誤在哪特別費(fèi)時(shí),尤其在初次接觸 AOP 和切入點(diǎn)時(shí)。有了靜態(tài)檢查,AspectJ 的編譯器會(huì)發(fā)出警告,指出無法解析的類型名稱或簽名。正如在后面討論的那樣,在即將發(fā)布的工具中,可以期盼獲得靜態(tài)檢查支持方面的提高。 未來構(gòu)建環(huán)境的考慮 如果選擇了 AspectJ 作為 AOP 工具,那么所有需要使用方面的 Java 項(xiàng)目都必須使用 AspectJ 的編譯器。對(duì)于某些項(xiàng)目來說,這可能存在問題(例如在集中指定生產(chǎn)構(gòu)建使用的編譯器的情況下)。從積極方面來說,AspectJ 編譯器打算替代 Java 編譯器。另一個(gè)有關(guān)的考慮是:每種工具因?yàn)樘砑訉?duì)方面的支持而帶來的編譯開銷各不相同。下一節(jié)將詳細(xì)討論這一點(diǎn)。最后,還應(yīng)當(dāng)記住 AspectJ 的語言擴(kuò)展方法要求項(xiàng)目中使用的所有與構(gòu)建有關(guān)的工具都要擴(kuò)展到 AspectJ。這意味著許多現(xiàn)成的解析 Java 代碼的工具無法用于 AspectJ 代碼(例如,基準(zhǔn)和報(bào)告工具,依賴性和風(fēng)格檢查器,以及版本控制使用的 語言擴(kuò)展在構(gòu)建集成上的利弊
雖然語言擴(kuò)展方法生來就有不足,但是它的一些優(yōu)點(diǎn)將來也可以應(yīng)用到注釋和 XML 風(fēng)格上。把這些優(yōu)點(diǎn)提供給注釋風(fēng)格,正是 AspectJ 和 AspectWerkz 兩個(gè)團(tuán)隊(duì)聯(lián)合進(jìn)行 @Aspect 開發(fā)工作的主要?jiǎng)訖C(jī),而且這還表明,如果使用底層的 AOP 編譯器,那么靜態(tài)檢查也能用于注釋風(fēng)格。目前,雖然還存在其他研究質(zhì)量的編譯器,但是 AspectJ 編譯器是惟一達(dá)到商業(yè)質(zhì)量的 AOP 編譯器。注意,與采用不同編譯器的必要性相關(guān)的許多關(guān)注點(diǎn)都是工具本身所固有的。在構(gòu)建時(shí)、裝入時(shí)或運(yùn)行時(shí)修改這些字節(jié)碼的時(shí)候,一些影響編譯新字節(jié)碼的問題也會(huì)出現(xiàn)。正如下一節(jié)將討論的,這個(gè)編織(weaving) 過程是所有 AOP 工具的基本過程,因?yàn)槭撬С謾M切關(guān)注點(diǎn)的模塊化實(shí)現(xiàn)。 編織和性能
AspectJ 和 AspectWerkz 都支持構(gòu)建時(shí)和裝入時(shí)編織,但是 AspectJ 更側(cè)重于前者,而 AspectWerkz 更側(cè)重于后者。JBoss AOP 和 Spring AOP 則側(cè)重于在運(yùn)行時(shí)使用動(dòng)態(tài)代理和攔截器調(diào)用方面。注意,也能將 Java VM 技術(shù)擴(kuò)展到支持運(yùn)行時(shí)編織,但目前這仍然處在研究階段。使用運(yùn)行時(shí)攔截框架的關(guān)鍵好處是:它很自然地?cái)U(kuò)展到了方面的熱部署(hot deployment)。這意味著可以在運(yùn)行時(shí)激活或禁用所應(yīng)用的通知。 熱部署是 JBoss AOP 的核心特性,它提供了一個(gè)應(yīng)用服務(wù)器管理控制臺(tái),可以激活和禁止某些方面。在 Spring AOP 中也有熱部署。加入 AspectWerkz 構(gòu)建和裝入時(shí)編織模型的類似擴(kuò)展也支持熱部署。在 AspectJ 中,用這種方式激活和禁止方面需要用通知中的 “ if” 測(cè)試或用 “if” 切入點(diǎn)進(jìn)行。有時(shí)用術(shù)語“動(dòng)態(tài) AOP”來描述熱部署,但是請(qǐng)注意,這個(gè)術(shù)語可能會(huì)造成誤導(dǎo),因?yàn)樗械?AOP 工具都支持動(dòng)態(tài)連接點(diǎn)模型。而且 Spring AOP 完全基于代理機(jī)制。因此,這種工具很適合粗粒度的橫切,但是純粹基于代理的 AOP 不能用來通知精細(xì)的連接點(diǎn)(例如方法調(diào)用或字段設(shè)置)。另一方面,可以在沒有構(gòu)建時(shí)或裝入時(shí)編織的情況下使用 Spring AOP 的代理,這對(duì)于某些應(yīng)用服務(wù)器的部署會(huì)非常有用。 性能考慮 也就是說,考慮一下AWBench 最新發(fā)布的 AOP 工具基準(zhǔn)會(huì)很有價(jià)值(請(qǐng)參閱參考資料)。要理解這些基準(zhǔn),需要考慮 AOP 工具進(jìn)行方面編織和編譯的不同技術(shù)對(duì)性能的影響方式。 AspectJ 在編譯時(shí)會(huì)帶來開銷,主要是內(nèi)存和時(shí)間的使用,因?yàn)樗窃诰幾g時(shí)執(zhí)行大部分通知。在大型項(xiàng)目中,這些開銷有可能是很可觀的,而且可能帶來一些問題,特別是面向方面編程的橫切特性通常意味著,在切入點(diǎn)發(fā)生變化時(shí),大部分系統(tǒng)都需要重新編譯。但它也意味著在運(yùn)行的時(shí)候,幾乎不需要為了匹配切入點(diǎn)做額外的工作。另外一個(gè)運(yùn)行時(shí)的性能優(yōu)勢(shì)來自 AspectJ 和 AspectWerkz 中連接點(diǎn)參數(shù)的靜態(tài)類型檢查。這會(huì)帶來性能飛躍,因?yàn)椴恍枰苑瓷涞男问皆L問連接點(diǎn)上下文了。對(duì)比之下,JBoss AOP 和 Spring AOP 基于攔截的技術(shù)在運(yùn)行時(shí)有更多的工作要做。因此,在 AWBench 基準(zhǔn)評(píng)定中可以看到一個(gè)趨勢(shì):AspectJ 的通知調(diào)用最快,然后是 AspectWerkz、JBoss AOP,最后是 Spring AOP。通過比較,AspectJ 的構(gòu)建時(shí)開銷最多,AspectWerkz 次之,JBoss AOP 再次,Spring AOP 沒有構(gòu)建時(shí)開銷。 攔截的性能利弊
與任何性能度量標(biāo)準(zhǔn)一樣,只能把這些準(zhǔn)則當(dāng)作參考,應(yīng)當(dāng)結(jié)合應(yīng)用程序和使用情況來考慮這些準(zhǔn)則。例如,與 Spring AOP 一起使用的典型粗粒度方面一般不會(huì)產(chǎn)生顯著的開銷。這里介紹的工具沒有任何一個(gè)有讓人無法接受的硬傷。與以前的一些 AspectJ 和 AspectWerkz 相比,這兩種工具進(jìn)行了更多的優(yōu)化,其他工具正在緊緊追趕。AOP 編譯器相對(duì)來說也是一種新發(fā)明,目前從研究社區(qū)到諸如 AspectJ 之類的實(shí)現(xiàn)的優(yōu)化速度也在加快。當(dāng)發(fā)生這些改進(jìn)的時(shí)候,正如我們期望看到的那樣,構(gòu)建時(shí)間會(huì)在不斷地改進(jìn)。 IDE 集成 在編輯切入點(diǎn)時(shí),不得不運(yùn)行系統(tǒng)才能查看結(jié)果,尋找受影響的連接點(diǎn)是非常耗時(shí)的。與此類似的問題是,開發(fā)人員在初次學(xué)習(xí) AOP 時(shí)經(jīng)常會(huì)問:“怎樣才能知道方面在系統(tǒng)上的效果呢?如果其他人簽入的方面會(huì)影響正在處理的方面又會(huì)怎樣呢?”通過指出什么時(shí)候連接點(diǎn)受通知影響,AOP 工具回答了這些問題。這意味著在處理某個(gè)方法的時(shí)候,可以看到影響該方法的所有通知。反過來,在編寫方面的時(shí)候,可以立即看到這個(gè)方面影響了哪個(gè)連接點(diǎn)。可以想像一下現(xiàn)代 Java IDE 是怎樣提供方便的導(dǎo)航方式的,可以從一個(gè)方法導(dǎo)航到所有重寫它的方法。這種面向?qū)ο蠊ぞ咧С质沟孟到y(tǒng)的繼承結(jié)構(gòu)清晰可見。而 AOP IDE 支持使得橫切結(jié)構(gòu)的效果清晰可見,從而使處理某些方面就像處理對(duì)象一樣容易。 插件比較 圖 2 演示了用于 Eclipse 的 AspectJ 開發(fā)工具(AJDT)如何在編輯器中呈現(xiàn)出橫切結(jié)構(gòu),以及如何呈現(xiàn)為了顯示方面聲明及其效果而擴(kuò)展的視圖。關(guān)于這些特性的詳細(xì)描述以及更多截屏,請(qǐng)參閱參考資料中的 AJDT 文章。 圖 2. 用于 Eclipse 的 AspectJ 開發(fā)工具(AJDT)插件 V1.2.0 下面將重點(diǎn)介紹一些 AJDT 插件的特性;列表編號(hào)與圖中的標(biāo)簽對(duì)應(yīng):
像 AJDT 插件一樣,JBoss AOP 插件也支持用視圖在橫切結(jié)構(gòu)中導(dǎo)航。在圖 3 中可以看到,Eclipse 的 JBoss AOP 插件提供了一些與 AJDT 插件相同的功能。它還有兩個(gè)顯著的額外特性:方面管理器視圖,用于查看切入點(diǎn)綁定;還有一個(gè) GUI,用于創(chuàng)建基于枚舉的切入點(diǎn)。表 2 提供了這些插件特性的完整比較。 下面將重點(diǎn)介紹一些 JBoss AOP 插件的特性;列表編號(hào)與圖 3 中的標(biāo)簽對(duì)應(yīng):
特性比較 下面的說明介紹了每種工具的 IDE 支持的關(guān)鍵特性:
所有的工具都依賴現(xiàn)有的 Java 調(diào)試器進(jìn)行啟動(dòng)和調(diào)試。在所有的工具中,包括那些沒有成熟 IDE 支持的工具(AspectWerkz 和 Spring AOP),方面程序的調(diào)試都工作得不錯(cuò)。這意味著在通知中和單步執(zhí)行(single stepping)中設(shè)置斷點(diǎn)與在普通 Java 類中是一樣的。 有可能錯(cuò)過的特性 支持在 IDE 中使用 UML 視圖的工具越來越多,盡管對(duì)這類視圖的應(yīng)用目前仍然存在爭(zhēng)議。目前,還沒有與 AspectJ 或其他 AOP 工具兼容的 UML 查看器。如果對(duì) AspectJ 程序使用 UML 查看器,查看器可能會(huì)崩潰,因?yàn)樗蟮氖瞧胀?Java 代碼。相比之下,普通的 Java 技術(shù)會(huì)把方面作為普通的 Java 類顯示。這樣做的好處是有限的,因?yàn)樗鼰o法顯示在通知與受影響的連接點(diǎn)之間,或者通知與通過類型間聲明添加的附加成員之間的所有有意義的關(guān)系。 文檔和庫 Spring AOP 提供了優(yōu)秀的庫支持。與 Spring 框架的集成意味著它利用了依賴注入的(dependency-injecting)方面,提供了復(fù)雜成熟的事務(wù)攔截器庫,而且支持一些有趣的第三方方面(例如 Acegi 安全性框架)。Spring 的 AOP 庫擁有在應(yīng)用服務(wù)器之間移植的優(yōu)點(diǎn),而且精心挑選的框架組件方式使它很容易接納模塊中其他利用 AOP 支持的部分。JBoss AOP 提供了與 JBoss 框架和 JEMS 堆棧的其他部分的良好集成,而且擁有目前能夠得到的最豐富的方面庫。這些庫包括對(duì) JBoss Cache、J2EE 按需使用、JBoss remoting、異步方面和 JMX 方面的支持。目前,雖然已經(jīng)用這些工具創(chuàng)建了一些第三方庫,但 AspectJ 和 AspectWerkz 不包括任何庫。未來的發(fā)行版承諾將提供庫支持。 下一步是什么 沿著這條路,對(duì) AOP 重構(gòu)的研究將會(huì)提供所有技術(shù)都能使用的結(jié)果。用于圖形選擇和切入點(diǎn)操作的 UI 將從一些常見的直觀推斷中受益,這些直觀推斷能夠?qū)⑦x擇和搜索結(jié)果轉(zhuǎn)換成切入點(diǎn)。UML 視圖也會(huì)開始顯示 AOP 聲明和聯(lián)合。全面支持這些新特性是有可能的,這要感謝一些領(lǐng)先的 AOP 工具在語義上的匯集。 長遠(yuǎn)來看,性能應(yīng)該是一個(gè)不是問題的問題。就像開發(fā)人員不該擔(dān)心虛擬方法分派的開銷一樣,他們也不用擔(dān)心通知的調(diào)用開銷。目前在很大程度上這是事實(shí),而且隨著編織器的改進(jìn),以及與 JIT 和 VM 的集成越來越緊密,情況還會(huì)變得更好。 還有另外兩個(gè)趨勢(shì)正在出現(xiàn),但是還不確定。首先,AOP 的連接點(diǎn)模型和切入點(diǎn)機(jī)制的適用性超越了編程語言,對(duì)于能夠從描述運(yùn)行時(shí)事件的簡潔語言中受益的其他工具來說,AOP 的連接點(diǎn)模型和切入點(diǎn)機(jī)制也很適用。隨著越來越多的人采用 AOP 工具,切入點(diǎn)的應(yīng)用在調(diào)試器、profiler 這類工具中的應(yīng)用可能越來越普遍。例如,可以在特定的控制流程中設(shè)置斷點(diǎn)。另一個(gè)正在出現(xiàn)的趨勢(shì)與模型驅(qū)動(dòng)的開發(fā)(model-driven development MDD)有關(guān)。由于橫切的問題在系統(tǒng)中是如此基本的一個(gè)問題,所以 MDD 工具會(huì)從模型化的橫切結(jié)構(gòu)以及生成的方面中獲益。 以下是期望從這些工具即將發(fā)布版本中得到的一些具體特性的列表:
底線 所有工具 VS 手工編碼的橫切
AspectJ
AspectWerkz
JBoss AOP
Spring AOP
結(jié)束語 仔細(xì)分析這篇由兩部分構(gòu)成 AOP 工具比較系列文章中討論的該工具的利弊,這些有助于判斷哪種工具最適合您的項(xiàng)目。文中指出了工具處理方面聲明、編織以及構(gòu)建集成的主要區(qū)別,概述了關(guān)鍵的性能問題;還強(qiáng)調(diào)了 IDE 集成的好處。本文概述了 Java 語言擴(kuò)展的優(yōu)勢(shì)與不足,這個(gè)主題對(duì) Java 開發(fā)人員有深遠(yuǎn)的意義,文章還指出了 AOP 工具的一些未來發(fā)展方向。 在閱讀本文時(shí),讀者可能會(huì)很驚訝地發(fā)現(xiàn)這些工具的相同點(diǎn)要多于它們的不同點(diǎn)。這意味著不管選擇哪項(xiàng)技術(shù),學(xué)習(xí)曲線可以從一個(gè) AOP 工具轉(zhuǎn)移到另一個(gè)。每種工具的新發(fā)展會(huì)繼續(xù)相互滲透。AOP 工具目前正在迅速發(fā)展,可以滿足不斷增長的用戶社區(qū)的需求;而且它還在不斷發(fā)布新版本。不管您最后采用什么樣的 AOP 工具,都鼓勵(lì)您加入它的用戶討論列表。您的反饋會(huì)幫助這項(xiàng)重要的技術(shù)指明未來的發(fā)展方向。 記著下個(gè)月繼續(xù)關(guān)注 AOP@Work 系列的下一期文章:Ramnivas Laddad 的 “元數(shù)據(jù)和 AOP:天生絕配”。
![]() |