程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> AOP@Work: AOP工具比較,第1部分-語言機制

AOP@Work: AOP工具比較,第1部分-語言機制

編輯:關於JAVA

簡介:AOP 技術的時代已經來臨,但是怎樣才能為項目選擇正確的工具呢?在 新推出的 AOP@Work 系列的第一篇文章中,面向方面(aspect-oriented)的編程 專家 Mik Kersten 將比較 4 個領先的 AOP 工具(AspectJ、AspectWerkz、 JBoss AOP 和 Spring AOP),幫助大家判斷應該選擇哪一個工具。本文由兩個部 分組成,在文中,作者將重點介紹這些工具的語言機制和不同技術的優劣。他分 別用 4 種工具編寫同一個示例,讓讀者感覺到它們之間的高級區別。他還將討論 每種工具的語法技術對 AOP 語義產生的效果。在文章結束時,作者將對工具的核 心語言機制(例如切入點匹配和組合、通知的格式、連接點上下文)進行深入比 較。注意,本文將解釋最近宣布的 AspectJ 和 AspectWerkz 項目合並的意義。

面向方面編程(AOP)在 Java™ 平台上變得日益流行。隨著 AOP 出版物和會議的增加,這項技術的工具與實現越來越多。雖然人們很清楚 AOP 是 面向對象技術的補充,但是 Java 開發人員該如何評估當前的 AOP 工具,特別是 每項新技術實現的優劣,這方面則相對不那麼清楚。

本文有兩部分,而且 本文還是 developerWorks 上一個新的 AOP 系列的第一篇文章。在本文中,將概 述 AOP 工具當前的技術狀況,比較對於該技術而言最成熟的一些方法:AspectJ 、AspectWerkz、JBoss AOP、和 Spring AOP,並對比與每種方法的采用有關的問 題。文中還會解釋最近宣布的 AspectJ 和 AspectWerkz 項目合並的意義(請參 閱參考資料)。

本文無意作為 AOP 的介紹或某個特定 AOP 實現的入門讀 物。而是將對目前使用最普遍的 AOP 技術進行概述。對每個工具的語言機制和工 具支持的內在優劣進行探討,將有助於為項目選擇最合適的技術。這裡定義的指 標還會讓讀者更加容易地評估即將推出的 AOP 工具和特性。關於 developerWorks 上介紹 AOP 的最新文章列表,請參閱參考資料。

請注意 本文有兩個部分,為了方便讀者,兩部分同時發布。第 1 部分側重於這 4 個領 先工具各自的 AOP 語言機制處理技術,其中包括工具的方面語法(aspect syntax)和切入點的表示、用來聲明方面的機制范圍等主題。第 2 部分繼續深入 介紹領先的 AOP 實現如何與現有的開發環境、工具和庫進行集成。這一部分包括 以下主題:方面設計器、IDE 插件、可伸縮性和 AOP 工具將來的發展方向,還包 括對最近 AspectJ 和 AspectWerkz 項目合並的關注。

選擇成熟的工具

AOP 是一項新技術,所以,並不是現有的所有工具都已經成熟到適用於商 業開發。判斷成熟度的一個主要因素是用戶的采用程度。在考慮把一項新編程技 術應用到商用之前,這項技術必須從活躍的用戶社區的反饋中得到強化。表 1 顯 示了 aosd.net 上列出的目前可以使用的 AOP 工具(請參閱參考資料)。每個工 具的用戶列表貼子數量可以表明它的用戶基數(省略了貼子的實際數量,因為單 獨一個月的統計可能給讀者造成誤解)。

表 1. 在 2004 年 11 月 AOP 工具用戶列表中的貼子數量

請注意 Spring 的 AOP 部分沒有形成一個獨立的下載或用戶社團,所 以用戶基數相當比例的用戶可能沒有給 Spring AOP 發貼,而是投在別的主題上 了。在 aosd.net 上還列出了 4 個額外的工具,但是它們要麼缺乏用戶討論論壇 ,要麼在 11 月沒有貼子。

AOP 工具雖然沒有列在表中前四位,但它在技 術上可能非常成熟,可是缺乏較大的用戶基數就意味著它們還沒有經受過采納程 度測試。雖然在本文編寫的時候,它們還不適合於商業開發,但是這些工具的日 後發展還是值得關注的。通過上表的比較,還可以看出非 Java 平台的 AOP 工具 沒有 Java 平台的工具成熟,但是應當注意 .NET 和 C++ 工具的用戶社區正在成 長。

根據表 1,可以看出,從用戶采用度的角度來說,AspectJ、 AspectWerkz、JBoss AOP 和 Spring AOP 是領先的工具。所有這些工具都是適合 用於商業開發中的開源項目。按字母順序將它們排列如下,包括它們 V1.0 版本 的發布日期:

AspectJ —— 2001 年由 Xerox PARC 的 AOP 小組發行。目前主頁在 eclipse.org 上,由 IBM 支持。版本已經更新到 1.2.1 。

AspectWerkz —— 2002 年發布,由 BEA Systems 支持。 版本更新到 2.0RC2。

JBoss AOP —— 2004 年作為 JBoss 應用程序服務器框架的擴展發布。版本 更新到 1.0。

Spring AOP —— 2004 年作為 Spring 框架的擴展發布。版本更新到 1.1.3.

都是為了連接點

本文介紹的每個 AOP 工具都采用了連接點(join point)模型和機制,顯式 地聲明程序的橫切結構。雖然各個工具實現這個框架的技術非常相似,但是理解 底層機制對於了解每項技術的優劣是非常重要的。在這一節中,將回顧 AOP 的連 接點模型以及利用連接點模型的語言模型。

支持機制

AOP 工具的設計目標是把橫切的問題(例如認證和事務管理)模塊化。在單獨 使用面向對象技術實現的的時候,處理這些問題的代碼會分散在整個系統中,這 種分散造成管理和發展橫切結構時出現不必要的困難。與對象提供了一種能夠清 楚地捕獲繼承結構的語言機制類似,AOP 也為橫切問題的良好模塊化提供了同樣 的好處。位於每個 AOP 工具核心的是連接點模型,它提供了一種機制,可以識別 出在哪裡發生了橫切。

連接點 就是主程序和方面相遇的地方。靜態連接點允許方面定義類上的新成 員。動態連接點是方面執行與程序執行相遇的地方。例如,普通的 Java 程序執 行方法調用、字段設置這樣的連接點。再比如說,請考慮一下這樣一個問題:對 改變 Account 狀態的活動進行監視,就像在 Ramnivas Laddad 的 AspectJ in Action 一書中討論的那樣(請參閱參考資料)。 圖 1 中的順序圖突出了在 Account 操作上形成的一些動態連接點。

圖 1. 突出了選中的動態連接點的 UML 序列圖

下面的編號與圖中的編號對應:

方法執行 連接點,與方法返回之前的生命周期對應。

控制流程 捕捉在控制流程序列中出現的各個連接點;在這個例子中,在 debit() 方法調用下方的序列描述了在 debit() 調用中發生的全部連接點。

字段訪問 連接點對應著字段的讀和寫;在這個例子中,在 Account 類上對 name 字段進行了賦值。

切入點、通知和類型間聲明

AOP 工具提供了識別連接點集合的機制,叫作切入點(pointcut)。通知 (advice) 機制指定在程序執行過程中遇到匹配的切入點時應當采取什麼行動。 另外,類型間聲明(inter-type declaration)(開放類或混合類提供了在現有 類型上聲明額外成員的方法。切入點、通知和類型間聲明組合在一起,使 AOP 語 言可以清楚地表達橫切問題。方面 聲明可以在標准的 Java 字段和方法之外包含 這三類成員。方面代表一套模塊化良好的橫切結構。如下所示,不同的 AOP 技術 實現這些方法的技術各不相同。但是,每種技術的核心,都是連接點的訪問、編 輯、命名和抽象機制。

切入點可以通過顯式枚舉方式描述連接點集合。應當用一個示例指定圖 1 所 示的 Account 的利息的三個方法調用。雖然枚舉可能很有用,但是用結構化屬性 的方式表示連接點通常更方便。這類基於屬性的切入點可以表示一套與“每個針 對 Account 子類型的調用”匹配的連接點,卻不必強迫程序員枚舉這些子類型。 這樣做可以保證向系統添加由 Account 擴展的新類時,新類會自動與切入點匹配 。

切入點支持復合(composition),這就允許把簡單的切入點組合成更復雜的 切入點。例如,可以把所有 Account 調用的切入點限制在那些針對特定類或控制 流程進行的調用中。切入點的命名(naming)機制提高了可讀性和復合性。對抽 象(abstraction)與具體化(concretization)的支持,可以更加容易地創建通 用庫,對於要應用庫的特定應用程序的切入點來說,這些庫可以獨立定義。最後 ,對切入點中公開連接點狀態 的支持允許對諸如正在執行對象和方法參數之類的 訪問事項進行商量。

方面比較

如前所述,所有 AOP 工具的底層機制都是連接點和切入點、通知和類型間聲 明的概念。在這些工具中,可以注意到的主要區別就是方面聲明編寫及應用到系 統上的方式。這些工具可用以下方法中的一種進行方面聲明:使用類似 Java 的 代碼、注釋或 XML。對於某些開發人員來說,熟悉用 Java 語言編程方面的知識 ,要比熟悉語言擴展技術的優劣更重要,這些內容會在後面的小節中討論。對於 其他人來說,了解注釋和 XML 技術在集成上的優勢,要比痛苦地把切入點當作字 符串來操作更重要。

在這一節中,將使用一個常見的示例指出每個工具在方面聲明技術上的差異。 請考慮圖 1 所示的 Account 類的授權策略這樣一個示例。在面向對象的實現中 ,最常見到的,就是對認證的調用分散在 Account 類的眾多方法以及需要認證的 其他類中。在 AOP 實現中,可以明確地用一個方面捕獲這個行為,而不必修改操 縱帳戶的代碼。不管使用什麼工具聲明,這個方面都需要具備以下特征:

一個切入點,捕捉 banking.Account 類上所有公共方法的執行。

一種引用正在認證的 Account 的方式。

通知,在切入點指定的連接點上調用 Account 的認證。

現在,請看這幾個領先的 AOP 工具各自是如何處理這個方面的。

AspectJ

Aspect 中的方面聲明類似於 Java 語言中的類聲明,如圖 2 所示。由於 AspectJ 是 Java 語言語法和語義的擴展,所以它提供了自己的一套處理方面的 關鍵字。除了包含字段和方法之外,AspectJ 的方面聲明還包含切入點和通知成 員。示例中的切入點使用了修飾符(modifier)和通配符(wildcard)模式來表 達“所有公共方法”。對帳戶的訪問,由 pointcut 參數提供。通知使用這個參 數,而切入點則用 this(account) 把它綁定。這樣做的效果,就是捕獲了正在執 行的方法所隸屬 Account 對象。否則,通知的主體與方法的主體相似。通知可以 包含認證代碼,或者就像在這個示例中一樣,可以調用其他方法。

圖 2. AspectJ 的方面

構建 AspectJ 程序與構建 Java 程序類似,其中包括調用 AspectJ 的遞增編 譯器,構建所有的項目源文件,包括普通的 Java 源文件。運行 AspectJ 程序也 與運行 Java 程序一樣,請注意要把 aspectjrt.jar 庫添加到類路徑中。要對在 系統中應用哪個方面進行配置,必須把它們加入包含列表或從中刪除,包含列表 會傳遞給編譯器,可以通過 IDE 支持傳遞包含列表,如果正在 Ant 環境或命令 行進行工作,也可以通過“.lst” 包含文件傳遞。注意,在第 2 部分中,將討 論構建 AOP 程序的細節以及方面設計的概念。

AspectWerkz

AspectWerkz 和 AspectJ 之間的重要區別就是: Authentication 現在是一 個普通的 Java 類,而不是一個方面。AspectWerkz、JBoss AOP 和 Spring AOP 都在沒有改變 Java 語言語法的情況下加入了方面語義。AspectWerkz 提供了兩 種進行 AOP 聲明的途徑。最常用的是注釋,注釋可以采用圖 3 中的 Java V5.0 風格,也可以為了與 J2SE V1.4 兼容采用 Javadoc 風格。AspectWerkz 還支持 另外一種基於 XML 的方面聲明風格。XML 風格與下面介紹的 JBoss AOP 的風格 類似,把方面聲明放在單獨的 XML 文件中。

請注意通知就是普通的方法聲明。按照約定,它被當作不同類型的方法聲明, 因為不應當顯式地調用它,而是應該在滿足特定切入點時自動運行它。 AspectWerkz 的切入點聲明是附加到切入點“方法”的字符串值,也可以在 XML 文件中獨立存在。所以,沒有切入點的 import 機制,所有的類型引用必須完全 規范。對正在運行的 Account 對象的訪問技術與 AspectJ 相同。請注意,規劃 的 @AspectJ 語法看起來與 AspectWerkz 注釋的語法非常相似。

圖 3. AspectWerkz 的方面

構建 AspectWerkz 程序會涉及一個標准的 Java 構建,然後會涉及到後處理 。要運行 AspectWerkz 程序,必須把 AspectWerkz 庫放在類路徑中。在使用不 可插入的方面的情況下,由 aop.xml 文件配置系統中一些方面的包含情況。

JBoss AOP

JBoss AOP 基於 XML 的方面來聲明風格,如圖 4 所示。JBoss 也支持與圖 3 所示相似的注釋風格。在 XML 風格中,方面、切入點和通知聲明都以 XML 形式 表示的。通知的實現,用的是普通的 Java 方法,由 JBoss AOP 框架調用。切入 點和切入點到通知的綁定都在方面中用 XML 注釋聲明。JBoss 沒有顯式地綁定 Account 參數,而是提供了對當前正在執行的對象的反射訪問,因此需要把類型 轉換到對應的類型。注意,即將發布的 JBoss 會提供一些靜態類型的切入點參數 來解決這一問題。

圖 4. JBoss AOP 的方面

用 JBoss 構建方面只包括普通的 Java 構建。JBoss AOP 的運行時截取框架 (interception framework)負責管理切入點匹配和通知調用。需要對啟動和類 路徑做一些配置,但是 JBoss AOP 的 IDE 插件替用戶做了這些工作。方面在 jboss-aop.xml 文件中配置。

Spring AOP

查看圖 5 中的 Spring AOP 示例時,可以注意到其中的 XML 比前面介紹的技 術多。與 JBoss AOP 類似,Spring 的通知實現是帶有特殊參數的 Java 方法, 由 Spring 框架調用。XML 描述 accountBean,Spring 框架通過它訪問 Account 對象,包括通知使用的攔截器 advisor 及其匹配模式,還有應用到模 式的向前(before) 通知。

圖 5. Spring AOP 的方面

Spring AOP 的技術雖然提供了更加精細的配置,但在將它用於 XML 時,它與 JBoss AOP 非常類似。構建、運行和配置 Spring AOP 方面的過程與 JBoss AOP 相同,但 Spring AOP 依賴的是 Spring 框架方便的、最小化的運行時配置,所 以不需要獨立的啟動器。請注意,使用這個技術,只能通知從 Spring 框架檢索 出的對象。

語法差異

正如上面的圖所展示的,AOP 工具之間的關鍵差異就是處理方面聲明的方式。 AspectJ 是 Java 語言的擴展,用它可以完全在代碼中對方面進行聲明。 AspectWerkz 和 JBoss AOP 支持用方面元數據對 Java 代碼進行注釋,或者在獨 立的 XML 文件中對方面進行聲明。在 Spring AOP 中,則完全用 XML 對方面進 行聲明。所以,在三種不同的技術中,對方面進行編程的感覺可能非常不同。用 AspectJ 的代碼風格,方面和切入點聲明感覺起來就像 Java 代碼。而 用 JBoss AOP 或 AspectWerkz 的注釋風格,感覺起來就像在現有 Java 元素上做的附加標簽。而用 Spring AOP 風格,以及 AspectWerkz 和 JBoss AOP 的 XML 風格 時,感覺就像使用獨立的聲明性 XML 語言。

每種技術都有它的優勢,具體要由使用者決定哪個更適合需求。所以在這一節 ,將簡要地討論一些能夠有助於進行決策的要點。

自己的風格是什麼?

不管選擇哪個 AOP 工具,使用通知主體時只涉及到使用 Java 代碼。如果需 要修改切入點,那麼區別是非常透明的。在使用 XML 風格時(就像在 Spring AOP 中),修改切入點包括:從通知找到 XML 文件中對應的切入點聲明。從正面 來說,這項技術把切入點和方面配置的工作全都局限於本地,但是如果要編輯許 多通知和切入點,而且要在 Java 和 XML 之間重復地翻來覆去,那麼這項工作就 會變得很繁瑣。

如果使用 AspectWerkz 或 JBoss AOP 提供的注釋風格,那麼就可以把切入點 的表達值從 XML 轉移到 Java 成員的注釋。這樣可以更容易地並發處理通知體和 切入點。如果選擇了 AspectJ 的代碼風格,那麼就會發現處理切入點感覺就像處 理代碼,而不像是處理非結構化的字符串值。從 Java 代碼能得到的一切(例如 “import”語句),都可以用於切入點。對比之下,如果用 AspectWerkz、JBoss AOP 和 Spring AOP 的 XML 和注釋風格,總是需要在規范切入點中的類型引用。

簡潔還是繁瑣?

方面聲明的風格對每個工具中使用的方面有很大的影響。例如,支持在 XML 中聲明方面的工具,也支持在同一 XML 文件中對方面應用到系統的方式進行配置 。在前面的小節中,只展示了切入點和方面聲明,但是類型間聲明同樣受到風格 選擇的影響。在 AspectJ 中,類型間方法聲明看起來就像正常的方法聲明,引用 的技術也一樣。而在其他技術中,則要指定一個類,擴展額外的混合類並繼承那 些額外的成員,通過注釋或 XML 添加新方法。注意,目前 AspectJ 是惟一提供 使用切入點的靜態強制機制的工具。表 2 比較了這些工具對 AOP 語法的關鍵元 素的處理技術。

表 2. 比較領先的 AOP 工具中的語法

顯然,從圖 2-5 的方面聲明來看,代 碼風格是處理 AOP 聲明最簡潔的技術。它不需要對通知命名,也不需要顯式地調 用通知。代碼風格不需要顯式地把通知綁定到切入點(就像 XML 風格那樣),也 不需要把通知綁定到 return 語句(這是 AspectWerkz 的切入點 “方法”所需要的)。對於可以在 圖 3 和 圖 4 的 XML 中看到的復雜設計, AspectJ 對 Java 語言進行的語法擴展允許直接表示這些設計。用 AspectJ 編寫 方面,感覺起來更像是編寫 Java 代碼,避免了冗余的鍵入,因此出錯也就更少 。從不好的一面來說,Java 的語法擴展代價巨大,而注釋和 XML 風格有它們獨 特的優勢。最明顯的就是 XML 風格可以控制切入點和通知的綁定。這對於擴展和 配置方面非常有益,在下面一節中將討論這點以及不同風格帶來的其他優缺點。

代碼風格與注釋和 XML 的比較

那麼,應當采用代碼風格,還是用注釋或 XML 聲明方面呢?以下是基於 AspectJ 的 Java 代碼的一些技術的優缺點總結:

簡明語法充分利用對 Java 代碼的熟悉,減少鍵入錯誤,使錯誤更少。

切入點是一級實體,因此更容易對它們進行處理。

對於許多開發人員,用 XML 進行聲明性編程要比用 Java 語言擴展更熟悉。

通知到切入點的綁定不能由開發人員控制。

如果這個小結仍然無法縮小決策范圍,那麼不要擔心。除了用每種風格編寫這 些方面的感覺之外,還有更多需要考慮的東西。當在下一節中查看語義的時候, 語法決策還會出現,而且也會影響在第 2 部分中討論的工具支持。

語義的相似性

雖然工具的方面聲明風格之間存在主要的語法差異,但是核心的 AOP 語義是 類似的。每個工具都有完全相同的連接點模型的概念,都把連接點作為 Java 程 序中的關鍵點,把切入點作為匹配連接點的機制,把通知作為指定連接點匹配時 執行操作的機制。

表 3 和 表 4 總結了每種技術的語義。您可以注意到,命令規范上有許多微 小的差異和變化,但是各種技術最終聚合在相同的核心概念上。這種聚合有很大 的好處,因為這意味著學習曲線很容易從一項 AOP 技術轉移到另外一項 AOP 技 術。剩下來要考慮的就是每種技術的差異所帶來的優劣了。

回到連接點

一個 AOP 工具連接點模型的表達方式決定了可用的連接點粒度,以及連接點 如何匹配。每個 AOP 工具都提供了大量用於連接點匹配的原生切入點。有些原生 切入點只與特定類型的連接點匹配(例如,方法執行)。其他切入點能夠根據連 接點的公共屬性(例如,在某個控制流程中的所有連接點)匹配任何類型的連接 點。連接點的類型以及它們特定的切入點,可以分成以下幾組:

調用(Invocation)—— 調用或執行方法和其他代碼元素時的點。

初始化(Initialization)—— 初始化類和對象時的點。

訪問(Access)—— 讀寫某些字段時的點。

異常處理(Exception handling)—— 拋出和處理異常與錯誤時的點。

另外,也支持以下沒有類型的切入點分類:

控制流程(Control flow)—— 在某個流程控制流程中的連接點。

包含(Containment)—— 與包含在某個類或方法中的代碼位置對應的連接點 。

條件(Conditional)—— 特定預測為真的連接點。

如表 3 所示,每個工具實現連接點模型的方式,以及它們用來匹配連接點的 原生切入點,都略有差異。注意,在某些情況下(在括號中表示),連接點不用 切入點標識。

表 3. 連接點和用來匹配連接點的原生切入點

要富於表現力還是要簡單?

在這裡主要的優劣在於富於表現力和簡單性的比較。更加完整和精細的切入點 集合允許通過方面訪問程序執行中更多有趣的點。例如,與持久性有關的方面可 能需要訪問對象的初始化連接點。但是這類完整性也會帶來額外的復雜性和更陡 峭的學習曲線。許多 Java 程序員並不區分調用和執行,而且沒有幾個人需要理 解初始化的微妙之處。而且許多常用的方面被當作是輔助性的,所以是否有表現 力與應用程序的功能並沒有緊密耦合。在常用的輔助性方面,例如監視和日志, 通常只利用了粗粒度的切入點(例如方法執行)。從反面來看,更廣泛的切入點 集合確實具備量入為出的屬性,因為切入點可以邊用邊學。如果不想用切入點制 作程序,那麼會造成面向對象代碼的強制重構,例如:以 init() 方法的形式公開類的初始化。

AspectJ 和 AspectWerkz 的連接點模型差不多完全融合,而且已經成為最近 的合並的關鍵促進者之一。JBoss AOP 模型幾乎同樣有表現力,只是為了簡單性 而遺漏了一些不太常用的連接點。一個明顯的差異是:在 JBoss Aop 中,不能把 控制流程表示成“在這個切入點的執行之下的所有連接點”。相反,程序員需要 手動列出調用堆棧中的每個調用。

Spring AOP 采用了不同的技術,目的是限制它的連接點模型的表現力。這使 它特別容易采用,而且對於一些粗粒度的橫切很有用。即將發行的版本將與 AspectJ 集成,提供與精細橫切機制的互操作性。

連接點模型的表現力與簡單性的比較

一些項目可以從更有表現力的連接點模型(例如 AspectWerkz、AspectJ 和 JBoss AOP 提供的)獲益,所以最好還是采用 Spring AOP 粗粒度的方便性?以 下是更有表現力的模型固有優缺點的一個總結,多考慮一下這些方面會對您有所 幫助:

了解更多知識 。

對於粗粒度的橫切和輔助性方面,只需要很少的切入點。

沒有精細的切入點,許多方面就不能表達。

使用新切入點的學習曲線是隨用隨學。

語言機制

我將用每種技術語言機制的詳細對比結束 AOP 工具比較的第一部分的討論。 表 4 是 4 個工具的 AOP 語言的概括。下面討論了最明顯的區別。

表 4. 領先的 AOP 工具的語義概括

切入點匹配和復合:AspectJ、AspectWerkz 和 JBoss AOP 提供了類似的類型 模式支持。它們三個都允許簽名方面的匹配,對於 Java 5 應用程序來說,這些 匹配包括注釋和泛型。AspectJ 和 AspectWerkz 提供了一種簡潔的引用多個類型 的技術(例如 Account+ 表示帳戶的所有子類型)。所有的工具都支持通配符匹 配。Spring AOP 還提供了對正則表達式的支持。雖然這看起來可能是一個強大的 優勢,但還是要指出其他技術已經選擇了放棄正則表達式,好讓切入點讀起來不 是太難,同時不會存在潛在的損害。切入點復合操作符基本上都是相同的。 Spring AOP 不提供“非”操作,這個操作通常與沒有在 Spring AOP 連接點模型 的容器(containment)連接點結合使用。

通知形式:AspectJ 支持比其他技術更多的通知形式,而 JBoss AOP 只支持 一種通知形式。每種通知形式都可以表達成 around 通知,所以 JBoss 的技術是 無限的,而且它確實提供了額外的簡單性。不好的一面是它損失了簡潔性,這一 點可以從需要進行額外的調用才能繼續執行原來的方法調用(如 圖 4 所示)看 得出來,而如果用 before 進行通知,這一點就是不必要的。還請注意,強迫通 知去遵守普通的 Java 規則(就像注釋和 XML 風格做的那樣),在一些情況下容 易出問題,因為這些規則是為方法設計的。AspectJ 擁有把被通知方法的異常“ 軟化”的能力,這很有用,但是不符合方法異常檢測的標准語義。

連接點上下文:在 AspectJ 和 AspectWerkz 中,通過指定和綁定切入點參數 訪問動態連接點的狀態,類似於在 Java 語言中聲明方法參數的技術(請參閱圖 2 和 圖 3)。這為連接點上下文提供了靜態類型化的好處。JBoss AOP 和 Spring AOP 反射性地訪問連接點的狀態,這消除了在切入點表達式中參數綁定的 復雜性,代價是參數靜態類型化。Java 程序員習慣了方法參數靜態類型化帶來的 好處,同時還可以從切入點參數的靜態類型化得到同樣的好處。所以,在 JBoss AOP 最近的發行版本中,有提供靜態類型化的“args” 的計劃。

實例化:在所有的工具中,方面的實例化是由 per 子句控制的。正如所料, Spring AOP 的實例化模型更簡單。對於額外的實例化機制的支持,則意味著可以 把方面編寫成只能應用於特定的動態上下文環境中,不用編寫代碼保存這個上下 文並測試其他方面是否該應用這個方面。主要的區別因素是 AspectJ 支持在每個 控制流程進行方面初始化,AspectWerkz 支持每個線程的初始化,而 JBoss 則支 持每個連接點的初始化。哪種最有用則取決於具體的需求。

擴展性:方面的擴展性支持庫方面的部署,這樣可以在日後為特定程序而將這 些庫方面具體化。例如,一個方面庫可以提供應用程序監視需要的全部邏輯和基 礎設施。但是,要采用某個特定項目的庫,那麼庫使用的切入點必須擴展成應用 程序特定的連接點。AspectJ 用抽象方面支持擴展性,抽象方面包含抽象的切入 點和具體的通知。擴展抽象方面的子方面必須具體化切入點。AspectWerkz 和 JBoss AOP 使用了完全不同的技術,沒有使用抽象切入點機制。擴展是通過生成 方面的子類、並在 XML 中或通過注釋定義新的通知綁定而實現的。切入點到通知 的顯式綁定為 AspectWerkz 和 JBoss AOP 提供了顯著優勢,從而可以很容易地 把方面擴展到新系統,無需要生成子類。方面庫的使用數據正在日益增多,這些 將決定與其他技術使用的 Java 風格的繼承和切入點綁定相比,AspectJ 特殊的 AOP 繼承形式是更好還是更差。

每項技術在處理 AOP 的語言機制時,都提供了自己獨特的優缺點。用一個簡 單的列表來總結這些優缺點是不可能的,因為對於不同的項目,每項技術的好處 是各不相同的。但是,以上信息為選擇工具或者遇到關鍵問題時尋找替代品提供 了指南。

結束語

為項目選擇一個 AOP 工具所面臨的難題在於比較每種工具的優劣,同時不要 讓自己迷失其中。AOP工具比較的第一部分強調了 4 種領先的 AOP 技術的核心機 制,並對比了它們的相似與不同之處。

如果本文是在十年之前報道一項新的模塊化技術,那麼我們可能就此打住,開 始用自己選擇的風格來編寫方面 —— 可能是在命令行用 Emacs 或其他文本編輯 器構建。但是今天,如果沒有深入研究一項新技術如何與現有的開發環境和其他 工具集成,人們是不會輕易地考慮采用它的。

所以,本文的第二部分把重點放在集成因素對 AOP工具選擇的影響。在其他因 素之中,將討論每個工具如何處理方面的編譯與設計,以及如何依據 IDE 集成與 工具支持將它們都組合在一起。我還會比較這些工具的基本特性,看看它們背後 到底是什麼,包括進一步探討 AspectJ 與 AspectWerkz 項目合並之後我們可以 期盼從中得到什麼。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved