AspectJ Development Tools for Eclipse (AJDT) 最近經歷了相當大的變化,主要是更加全面地與 Eclipse 平臺集成在了一起。這一變化為 AspectJ 開發人員提供了對 Eclipse 平臺上的工具支持的更多訪問。在本文中,我將介紹適用于 Eclipse 3.0 的 AJDT 1.2,它是在今年 6 月發布的,還將介紹適用于 Eclipse 3.1 的 AJDT 1.3,它將于今年 9 月發布(現在可以得到早期的 development builds 版本)。
自 AJDT 1.1 起,AJDT 已經發生了很大變化,所以這篇文章對新接觸 AJDT 和熟悉早期版本的開發人員都很有用。在本文中,我不想重復指出發生了什么變化和這些變化是如何發生的,而是打算將用新的觀點來觀察目前的 AJDT 功能和技術。
在整篇文章中,我都會使用一些常見的場景來探索 AJDT 的功能。所有場景都將反映典型的 AspectJ 開發人員經歷的活動;例如,第一個場景涉及如何從頭開始創建簡單的 AspectJ 項目(開發人員開始熟悉 AspectJ 或者開始熟悉語言和工具時最常做的一件事)。更深入的場景包括:向現有 Java 項目添加方面、處理各種各樣的多項目環境。我還將討論對 AspectJ 5 中新特性的特定支持,并帶您經歷從 AJDT 1.1 中進行遷移的過程。最后,在對本文進行總結時,我將簡要介紹 AJDT 開發過程本身(即用 AJDT 開發 AJDT)以及未來您可以參與的一些變化。
![]() |
|
請注意,AJDT 1.2 是適用于 Eclipse 3.0 的最新穩定發行版,它替代了 AJDT 1.1.12,而 AJDT 1.3 則是適用于 Eclipse 3.1 的穩定發行版。AJDT 1.2 的 Milestone 版本和 development builds 版本已經可供 Eclipse 3.1 使用,但是要實現適用于 Eclipse 3.1 的穩定發行版,還需要一個獨立的版本分支,所以出現了 AJDT 1.3。除了特別指出的之外,本文描述的每件事都適用于兩個版本分支。主要的區別在于特定于 AspectJ 5 的功能,它通常要求使用 Eclipse 3.1。
請參閱 參考資料,下載 AJDT 和 Eclipse 平臺的當前版本。兩者都需要下載,以運行本文中的示例。
從頭開始學 AJDT
對于剛剛開始接觸 AspectJ 的 Java 開發人員,編寫一些簡單的 AspectJ 程序是一種好的做法??梢允褂?AspectJ 編程人員指南中的示例,或者使用眾多優秀的 AspectJ 書籍或文章(請參閱 參考資料 一節)來完成這項任務。在 Eclipse 中創建新 AspectJ 項目的過程與創建 Java 項目的過程很相似:只需選擇 File > New > Project > AspectJ Project,或者使用工具欄上的 New AspectJ Project 快捷方式即可。向導的其余部分與 New Java Project 向導基本一樣。
實際上,AspectJ 項目就是 Java 項目(從 Eclipse 的角度來看,它在具有 AspectJ 性質 之外還具有 Java 性質),所以任何可以在 Java 項目上使用的工具和插件也可以在 AspectJ 項目上操作)。關鍵的區別是用來編譯項目的 Eclipse 構建器:AspectJ 編譯器被用來取代 JDT Java 編譯器。AspectJ 編譯器是 JDT 編譯器的擴展,所以完全能夠編譯 Java 代碼。
在下一小節中,我將介紹在簡單開發場景中發揮作用的一些 AJDT 特性。
New Aspect 向導
由于 AspectJ 項目和 Java 項目非常相似,所以我不需要解釋如何創建源文件夾、包和類,或者如何配置項目的類路徑 —— 對于多數 Eclipse Java 開發人員而言,這些都應當是非常自然的事(請參閱 參考資料,以獲得有關 Eclipse 的更多信息)。同樣,編輯類的體驗也與以前一樣:仍然可以用 Java 編輯器,并且您會發現一些可以極大地節約時間的特性(像內容輔助、快速修復和組織導入)仍然有效。
所以我們直接介紹下一步:創建方面。方面 是 AspectJ 的模塊化單元,與 Java 語言中的類有許多共同之處。請選擇 File > New > Other > AspectJ > Aspect 或使用工具欄上的 New Type 下拉列表來打開 New Aspect 向導,它與 New Class 向導非常相似,只有少數選項不同。
AspectJ 編輯器
在創建新方面之后,會看到它在編輯器中打開(這時是 AspectJ 編輯器),您可能會注意到,所創建文件的擴展名是 .aj,這是 AspectJ 中指定的方面擴展名(類保存在 .java 文件中)。請試著在新方面中輸入一些 AspectJ 代碼。您會發現,編輯器的功能與處理 Java 代碼的功能非常相似。例如,請考慮以下特性:
一切都非常熟悉,不是嗎?也有一些事被遺漏,其中包括方面中的快速修復和某些事情的內容輔助(例如切入點名稱),這些將由 AJDT 未來的版本解決。
保存方面會導致對項目進行編譯(除非禁用了自動構建,如果這樣的話,則需要按下 Build 按鈕,就像處理 Java 項目那樣)。如果方面包含影響項目中的代碼的通知(advice),那么應當看到 Cross References 視圖中出現一些條目,并且編輯器的左側會出現一些標記。AJDT 提供了兩種向您展示 AspectJ 項目的橫切特性的方法。
橫切視圖
可以將 Cross References 視圖和 Outline 視圖視為合作伙伴。Outline 視圖顯示當前文檔的結構,而 Cross References 視圖顯示當前元素的橫切關系。一個很有用的布局是將 Cross References 視圖放在 Outline 視圖下,如下面的圖 1 所示。如果看不到這個視圖,可以選擇 Window > Show View > Other > AspectJ 打開它,或者可以在 Outline 視圖中的某個元素上右擊,并從上下文菜單中選擇 Open Cross References。
在編輯器中的方法內部單擊會使 Cross References 視圖顯示該方法的橫切信息,如圖 1 所示:
在該例中,您可以看到,這個方法正通過 GetInfo
方面中的一些 around 通知來獲得消息??梢栽谕ㄖ蠁螕?,以便直接導航到它。然后通知本身就會顯示在圖 2 所示的 Cross References 視圖中,這樣就可以從另一個方向查看它們之間的關系:
也有選項可以不 把 Cross References 視圖與編輯器連接。如果采用了這一選項,那么 Cross References 視圖不會響應編輯器和 Outline 視圖中的選擇,如果想一直能夠看到某一列橫切信息,那么這樣做可能很有用。另外一個選項是顯示當前文件整體的橫切信息,而不僅僅顯示當前元素的橫切信息。
最后,有些開發人員選擇不讓 Outline 視圖一直可見,因為它會占據寶貴的屏幕空間。相反,他們使用 Quick Outline(從 Navigate 菜單中選擇,或者更典型的做法是按下 Ctrl+O),這是該視圖的一個權宜版本,出現在編輯器上方。按下 Ctrl+Alt+X(也可以通過 AJDT 選項配置頁自己配置鍵綁定) 將顯示 Quick Cross References 視圖,如圖 3 所示。使用 Quick Outline 視圖,再次按下鍵綁定,這會導致該視圖也顯示所繼承的成員。Quick Cross References 視圖使用類似的機制在當前元素的橫切信息顯示與整個文件的橫切信息顯示之間進行切換。
標記和圖像修飾器
如果查看編輯器中建議的源代碼,就會看到編輯器左手邊的標記圖標。這些標記將指出通知的存在和類型,使用的圖標與 Outline 和 Cross References 視圖中的圖標相同。有一些分別表示 before、after 和 around 通知的不同圖標。每種圖標都有兩個變體:有小問號的和沒有小問號的。問號表明存在運行時測試,以確定是否在這個位置應用通知,例如什么時候在切入點中使用 cflow
指示器。沒有問號的變體用在編譯的時候就可以完全確定匹配的地方。
如果在標記上右擊,就會在上下文菜單中看到 Advised By entry,以及一個顯示通知的來源的子菜單。如果選擇其中的一個條目,編輯器會打開并顯示這個通知。在通知中會看到額外的標記,這些標記從另一個方向顯示橫切關系,并且還帶有一個 Advises 子菜單,如圖 4 所示。這些對稱的標記支持在通知的源和目標之間進行一致的導航。類似的標記和子菜單也可以用來表示其他橫切信息,例如類型間聲明。
圖像裝飾器也可以用來表示橫切信息。如果回過頭來看一下 圖 1 所示的 Outline 視圖,就會看到在視圖的三個方法的左邊有一個小的橙色箭頭。這個箭頭是 Eclipse 用于 Java 元素的圖像裝飾器??捎盟硎局付ㄔ厥欠袷芡ㄖ闹苯佑绊?,或者是否包含正被通知的連接點。這個有幫助的可視線索會在任何 Java 元素出現的地方出現,其中包括 Outline 視圖、Cross References 視圖和 Java Browsing perspective 中的 Members 視圖。
![]() |
|
轉換 Java 項目
從簡單的測試項目得到 AspectJ 和 AJDT 的一些經驗之后,開發人員的下一步通常是采用一個現有的 Java 項目,嘗試在一個或兩個方面擴展它。例如,您可能想添加強制方面,例如檢測對 System.out.println
或 Exception.printStackTrace
意外調用的方面,或者 生產方面,例如實現持久性的方面,或者某個設計模式的面向方面實現。
將 Java 項目轉換成 AspectJ 項目很簡單。只需在項目上右擊并選擇 Convert to AspectJ Project 即可。從 Eclipse 的角度來說,是將 AspectJ 性質添加到項目中,并轉而使用 AspectJ 編譯器,就好像從頭開始創建 AspectJ 項目那樣。這個過程沒有什么需要多提的,它可以應用到任何具有 Java 性質的項目上,其中包括更高級的項目,例如 Eclipse 插件項目。這個過程也是可逆的,也就是說,可以使用上下文菜單項來刪除 AspectJ 性質并切換回 Java 編譯器。
一旦用 AspectJ 項目替代了 Java 項目,您可能想知道它們的區別是什么。至少最初的答案是“它們的區別非常小”。您可以繼續在 Java 編輯器中編輯 Java 類,采用標準的文檔大綱視圖和以前一直使用的所有特性(包括快速修復、內容輔助以及通過紅線得到早期錯誤提示)。同樣,把更改保存到類中會導致對項目進行快速遞增編譯,您也可以從項目的屬性頁面上設置所有相同的編譯器選項。每個合法的 Java 程序都是合法的 AspectJ 程序,所以可以像以前那樣編譯代碼。
實際上,AspectJ 編譯器是 Eclipse Java 編譯器的擴展,而 AJDT 則盡可能一致、透明地擴展 JDT 工具。這就是我們談到無縫集成時所指的內容。這是 AJDT 1.2/1.3 的主要重點領域之一,而且我們已經取得了好的進展(我在文章后面部分會指出一些仍然存在的限制)。無縫集成的目標是讓切換到 AspectJ 項目的第一步變得盡可能的容易;這為從使用方面進行編碼中獲得實際有用的東西鋪平了道路。
![]() |
|
管理多個項目
構建 AspectJ 源代碼需要兩個不同階段:編譯 .java 和 .aj 文件中的源代碼來生成 .class 文件,然后將方面應用到生成的 .class 文件中。第二個階段稱為編織,這是 AspectJ 和 Java 編譯器的主要區別。Java 編譯過程由類路徑設置控制,這使得這些類型可以通過編譯器用于解析。AspectJ 編譯過程也使用相同的類路徑設置,該路徑的配置方式與 Eclipse 中的完全相同。但是,這個設置還不足以控制所有情況下的編譯和編織步驟。這就是 AspectJ 項目中還有兩個額外設置的原因。
首先,有一個 inpath 設置。這里指定的任何內容編織器都可以使用,所以任何應用到的方面都會被編織進來??梢酝ㄟ^在項目上右擊并選擇 Properties,然后進入 AspectJ InPath 區域,將條目添加到項目的 inpath 中。條目可以是 JAR 文件或目錄(類文件夾),例如其他項目的 bin 目錄。inpath 中的內容都被發送到項目的輸出中,可能是在使用方面編織之后)。
第二個附加選項是 aspectpath。inpath 控制著將要編織的事物的列表,而 aspectpath 控制將那些內容編織到這個列表。換句話說,在 aspectpath 上指定的方面對編織過程是可用的,就好像它們存在于項目源目錄中一樣。這個設置由 AspectJ Aspect Path 屬性頁控制,可以包含 JAR 文件或目錄。
每個項目的屬性頁的 AspectJ 區域中還包含 output JAR 設置。這個設置使編譯器將類文件直接輸出到 JAR 文件,而不是輸出到項目的輸出文件夾。
使用其他項目的方面
要想查看以上設置的實際效果,請考慮一個示例工作空間。假設有兩個項目,一個叫做 MyAspects,另一個叫做 WeaveMe。兩者都是 AspectJ 項目,不過第二個本身可能不包含方面。MyAspects 項目包含一些 WeaveMe 項目要求的方面。要連接兩個項目,只需在 WeaveMe 項目上右擊,然后選擇 Properties 并進入 AspectJ Aspect Path 區域即可。接著,在 Libraries 選項卡中按下 Add Class Folder,并選擇 MyAspects 項目的 bin 目錄(或者任何輸出目錄對應的名稱)。
按下 OK 用這個新設置構建項目,假定方面中的切入點與 WeaveMe 源代碼中的位置對應,因此將應用對應的通知。編輯器的標記和 Cross References 視圖仍會顯示“advised by”關系,但是現在關系的始發端被描述為一個二進制方面,所以不能導航到它。這是因為一般來說,方面可以位于 Eclipse 工作空間以外的地方(例如外部 JAR文件)。但是,至少在這個示例中,源代碼仍然在工作空間之內,只不過是在另一個項目中,所以希望 AJDT 的未來版本能夠做好這個連接,并允許導航到其他項目中的方面。
需要著重指出的是,通過 aspectpath 提供的類型在運行時也需要能夠使用。幸運的是,AJDT 使這一點變得很容易 —— 不必選擇 Run > Java Application,可以使用新的啟動配置 Run > AspectJ/Java Application。這與 Java 啟動配置相同,惟一區別是它自動向運行時類路徑添加了 aspectpath 條目。另外,還有一個無關的區別是,AspectJ/Java 啟動配置也可以定位到方面中包含的任何主方法。
編織 Java 項目
如果有一個項目包含 Java 代碼,或者以源代碼的形式,或者以 JAR 文件的形式,倘若現在想在它上面應用某些方面,那么該怎么辦呢?如果需要保持方面與項目分離,那么可以把它單獨作為一個 Java 項目,并創建一個 AspectJ 項目進行編織。在這種情況下,只要在 AspectJ 項目中添加“AspectJ InPath”設置并引用 Java 代碼即可,可以使用 Add JARs 或 Add Class Folder 按鈕添加設置。
在像這樣進行二進制編織的時候,沒有源代碼標記來顯示通知發揮效果的地方。編譯器選項在這里會有幫助:在 AspectJ 項目的 AspectJ Compiler 設置的 Other 選項卡中(或者從全局選項參數設置中),選擇 Output weaving info messages to problems view 選項?,F在,不論何時構建項目,Problems 視圖都會顯示信息條目,指出編織進去了哪些類型,如圖 5 所示:
注意,如果輸入的是 JAR 文件,那么可能要使用前面提到的 Output JAR 選項直接生成初始 JAR 文件的編織后版本。
開發 Aspect 庫
可重用方面庫的概念是一個非常強大的概念。假設已經開發了一個方面,并且感覺它適用于其他項目,那么可以泛化這個方面,并把它隔離到自己獨立的項目中,形成一個庫。通常,庫中的方面應當定義適當的行為,然后可以根據需要將它裁剪為符合特定目的。這很有可能涉及一個帶有抽象切入點的抽象方面。然后,使用方面的項目就可以用切入點擴展它,切入點定義了將要應用的方面的適當范圍。
如果使用方面庫的項目包含任何必要的抽象方面的具體版本,那么只需要從 Java Build Path 屬性頁將庫項目添加到 Projects 選項卡中,就可以把兩個項目連接起來。由于具體方面對項目而言是本地的,所以常規的類路徑查找就足以解決超方面的問題。
還要注意的是,編輯器標記和 Cross References 視圖把通知的源顯示為抽象超類。這樣做是正確的,因為這就是通知所在的位置;但是在這種情況下,具體方面中的切入點控制著通知的應用,而這常常是一個很有趣的地方。在 AJDT 的未來版本中,可能會公開“使用切入點(uses pointcut)”來幫助實現這個連接。由于可重用方面庫的潛力,所以可以預期,在 AJDT 后續的發行版中,這一領域的通用支持會有所增加。
處理插件項目
Eclipse 平臺的日益流行意味著越來越多的開發人員在構建插件。好消息是使用 AspectJ 處理插件很容易。只需采用一個插件項目,在該項目上右擊,并用與處理 Java 項目相同的方式將它轉換成 AspectJ 項目即可。系統會提示您添加對 org.aspectj.runtime 插件的依賴關系。AspectJ 程序在運行時對 aspectjrt.jar 文件存在依賴,而對于插件項目來說,這個依賴關系可以通過小的 org.aspectj.runtime 插件來滿足。將這個依賴關系添加到項目之后,就可以在未來的插件開發中使用方面了。
![]() |
|
Eclipse 插件開發環境 (Plug-in Development Environment,PDE) 允許為插件項目生成 Ant 構建文件(build.xml)。AJDT 為支持 AspectJ 的插件項目提供了類似選項。在 plugin.xml 文件上右擊,并選擇 PDE Tools > Create Ant Build File with AspectJ Support。生成的 build.xml 文件與為 Java 插件項目生成的文件類似,差別在于不使用 javac
Ant 任務編譯源代碼,而是用 AspectJ 提供的 iajc
任務。
![]() |
|
管理大項目
現在您已經看到,在 Eclipse 平臺上用 AJDT 創建簡單項目是多么容易,并且我們還查看了如何將 Java 項目遷移到 AJDT,如何用 AJDT 管理、處理多個項目和項目類型。接下來,我將介紹一些特別適合具有大量源文件的項目的 AJDT 特性,并提供一些使用它們的技巧。
項目級可視化
正如前面看到的,AspectJ 編輯器中的標記和 Cross References 視圖清楚地在每個文件的基礎上表現出了橫切的特性。無法從這些特性中得到的只是對關注點的廣泛分布的總體概括 —— 例如,它是否橫切整個項目或只是橫切幾個包。要想得到這類觀察,可以使用 Visualiser。
打開 Visualiser 最簡單的方式就是切換到 Aspect Visualization 視圖,它代表選中項目的可視化表示,所選中項目由一些列組成,一個源文件一欄,列的高度與源文件的行數成正比。欄上不同位置的條帶被涂上了不同的顏色,用來表示通知發揮作用的源代碼位置(在進行其他運行時測試的情況下,可能會發揮作用)。每個條帶的顏色對應著包含這條通知的方面??梢栽趫D 6 的屏幕快照中看到這一點:
可以看到,有一個主 Visualiser 視圖和一個輔助 Visualiser Menu 視圖,這個視圖中列出了被顯示的方面??梢詮牧斜碇腥∠麑Ψ矫娴倪x擇,把它們從可視化中刪除。例如,您可能想刪除一個到處都有、擋住其他方面的日志方面??梢杂?Visualiser 視圖工具欄上的控件放大或縮小視圖,使內容適合于視圖(有一個最小尺寸的限制),或者只顯示受通知影響的欄(不受影響的欄以灰色顯示),并把分組級別從類視圖切換到包視圖(在包視圖中,包中的所有類都被組合到一欄中)。最后,可以使用下拉菜單訪問其他選項,例如參數設置頁,在這里,可以進一步對呈現方式進行定制。除了顯示通知的效果之外,可視化還包括“declare error”和“declare warning”語句位置的匹配??梢詮?Visualiser 菜單的工具欄中切換這些選項的開關。用來表示不同方面的顏色也可以從列表中進行修改,而選中的顏色會被記住。
Visualiser 的設計目標是處理大型項目,雖然要求用同樣多的處理來決定每個類的大小并使其可視化。由于可用的圖形內存通常比通用內存更有限,所以已經對呈現過程進行了優化,將圖形內存的使用控制在最小。只在需要欄的時候才呈現它們,所以第一次滾動視圖時不像之后滾動它時那么順暢。通用內存用于緩存圖片數據,除非通用內存不足。在內存不足時,每次都會重新生成圖像數據。這意味著更大的項目也能顯示,但是由于內存有限,在滾動時,響應可能不是很快。
Visualiser 支持一個選擇機制,該機制可以通過鼠標或鍵盤操作來選擇欄、類或條帶。激活某一個選擇(通過雙擊鼠標,或按下空格鍵)會讓對應的項目在編輯器中打開。值得指出的是:Visualiser 實際是一個完全通用的組件,可以將它更改為能夠對任何東西(從 Eclipse 標記到 Google 搜索結果)進行可視化。除了向 Visualiser 提供定制數據之外,還可以定制欄的繪制樣式和條帶使用的顏色。請參閱 參考資料,以獲得更多信息。
管理變化
項目的開發過程中,代碼中不斷發生變化。隨著代碼的重構、bug 的修補和新特性的實現,類和方法不斷被添加、刪除和改名。在大型項目中管理這些變化是非常具有挑戰性的,特別是在有大量橫切功能的時候??梢杂梅矫娌东@這個功能,由于把相關代碼收集在一起,而不是散落在代碼基的各處,所以可以改善這種狀況。然后可以用切入點來定義將在其上應用方面中的通知的連接點。但是,隨著上述變化不斷發生,甚至連匹配位置也可能發生意想不到的變化。
解決這個問題的第一個方法是從一起開始就開發健壯的切入點。在更改代碼之后,構建良好的切入點不太可能停止匹配所需的位置。例如,如果對調用采用 integer 作為自己的第一個參數的 update 方法感興趣,那么可以使用 call(* update(int))
這樣的切入點。它會與所有帶有單一 integer 參數的 update 方法調用進行匹配。但是,如果后來有人向該方法中添加了其他參數,切入點就不再匹配。如果只對第一個 integer 參數感興趣,那么更好的切入點應當是 call(* update(int,..))
,因為即使添加或刪除額外參數,這個切入點仍然會匹配。
即使有這些預防措施,有些類型的變化仍然可能給最健壯的切入點帶來問題;例如,在以上示例中,方法參數可能這樣變化:您所感興趣的 integer 不再是第一個參數。另外一種變化可能造成切入點在更多地方開始進行匹配,而不是在所要求的地方。例如,如果對 setter 方法感興趣,那么切入點中可能應用了 set*
模式,但是后來代碼中添加了一個叫做 setup
的非 setter 方法,這會造成切入點意料之外的額外匹配。
新的 橫切比較(Crosscutting Comparison) 功能(及時為 AJDT 1.2.1 和 1.3 版本添加的功能)—— 就是為了幫助處理代碼的這類變化而開發的。橫切比較允許對項目中的橫切關系制作一個快照,然后用快照與該項目以后的版本中存在的關系進行比較。要創建快照,請在項目上右擊,然后選擇 AspectJ Tools > Save Crosscutting Map。系統會提示輸入保存關系圖的文件名。這些文件的擴展名是 .ajmap,可以將這些文件直接保存在項目中。例如,在發布項目的某個具體版本時,可以保存這個發行版的橫切關系,以便在開發下一發行版時將它們作為參考點。
一旦項目中有了一個或多個橫切圖文件,就可以進行比較了??梢杂脙蓚€文件相互比較,也可以用一個文件中的關系與當前構建中存在的關系進行比較。要使用這兩個選項,可以在包瀏覽器中選擇一個或二個圖文件,然后從上下文菜單中選擇適當的選項。比較的結果會在新視圖中顯示出來,如圖 7 所示:
這個視圖顯示了自從第一個圖文件記錄以來添加的橫切關系,以及刪除的關系(即在第個圖文件或當前構建中不存在的關系)??梢噪p擊源和目標元素,在編輯器中打開它們(當然,不存在的元素除外)。在工具欄上有一個過濾器按鈕,可以限制顯示的關系集。默認情況下只顯示一個方向的關系,例如,顯示了“advises”,就不同時顯示“advised by”。您還可以單擊欄標題,根據這一欄對結果進行排序。最后要注意的是,如果選擇了用圖文件與當前構建進行比較,那么每次進行構建時,就會重新進行比較。這可以提供有關創建圖文件以后發生的變化的持續觀察,這在重構項目中的代碼時非常有用。
內存使用
一般來說,AspectJ 項目使用的內存在兩個方面要比 Java 項目使用的內存多。首先,是在編譯器上。面向方面的編譯器所做的工作要比面向對象的編譯器做的工作多得多,因為它要執行編織過程。第二,開發環境需要額外的工作才能讓應用程序的橫切結構顯現出來。雖然這個負荷不能完全避免,但 AJDT 和 AspectJ 編譯器的未來發行版會重點減少它。
如果正在處理大型項目,那么要采取的第一步通常是改進運行 Eclipse 的 Java 進程的內存總量。要做到這點,可以向 Eclipse 進程傳遞一個參數,比如 -vmargs -Xmx512m
。如果不需要同時打開工作空間中的所有項目,那么可以關閉其中一些項目。如果仍然發現內存不足,那么可以對項目進行安排,例如有些代碼是通過 Java 編譯器編譯的,包含通過二進制編織或加載時編織應用的一些方面。另一個選項是使用 AspectJ 編譯器設置的“Other”選項卡,在每項目基礎上,或者在整個工作空間范圍內,禁用橫切結構模型的創建。這樣做可以節省內存,但是應當只將此作為最后一種方法使用,因為如果這樣做,就看不到任何通知標記,而 Cross References 和 Visualiser 視圖也不會顯示任何橫切信息。
![]() |
|
AspectJ 5 中的新內容
正如我前面提到過的,多數特定于 AspectJ 5 的功能只在 Eclipse 3.1 中才有,因為它要求的 Java 5 支持在 Eclipse 3.0 中不存在。所以,除非特別指出,否則這一節中的內容只適用于 AJDT 1.3。上個月的 AOP@Work 系列“AspectJ 5 簡介”介紹了 AspectJ 5 中的新特性,所以在這里只討論它們對 AJDT 的意義。但是,請注意,在 AspectJ 項目中使用 Java 5 模型所需的步驟與 Java 項目中的相同。選擇 Java > Compiler,然后將 compiler compliance level 設置為 5.0。還需要保證項目的構建目錄中的 JRE 系統庫是 Java 5 的系統庫,而不是 1.4.2 或更早的版本。
AspectJ 5 中的少數變化不需要 AJDT 做任何變化,例如語義變化或附加的 API 類。有些變化,例如新的 pertypewithin 方面實例化模型,只要求高亮顯示編輯器中的語法,而且在這種情況下,在 New Aspect 向導中會出現額外的復選框。其他變化要求的工作略多一些,您很快就會看到。還需要注意的是,在許多情況下,AJDT 開發小組已經首先實現了最底級別的支持,留下了日后添加更多功能的空間。
添加到 Java 5 和 AspectJ 5 中的注釋已經廣為人知。因為 AJDT 擴展了 Eclipse 中的 JDT,所以它自動得到了這里添加的注釋支持的好處。AspectJ 5 添加了新的切入點指示器,例如根據注釋是否存在而進行匹配的 @this
。這些要求在編輯器中高亮顯示語法。AspectJ 5 中還添加了一種新的聲明語句,用來在類型、方法、構造函數和字段上聲明注釋。通過添加了兩個新的橫切關系“annotates” 和“annotated by”,新的聲明語句在 AJDT 中受到支持,它們顯示在 Cross References 視圖和標記的上下文菜單中,就像“advises”和“advised by”那樣。
在圖 8 中可以看到新的聲明語句的簡單示例。其中的方面包含一條 declare @method
語句和一個類型間聲明。方面被選中,所以 Cross References 視圖顯示方面中每件事的橫切信息。declare @method
語句注釋了三個方法 —— 一個是類型間聲明,另外兩個直接在 Aclearcase/" target="_blank" >ccount 類中。類型間聲明被顯示為“declared on”(在...上聲明)在 Account 類上,而且由 @method
聲明“annotated by”(由...標注)。還請注意,編輯器中 @method
聲明的標記和類型間聲明上的雙向箭頭,因為它既是橫切關系的源,也是目標。
AspectJ 5 的另外一個新特性是對基于注釋樣式的方面聲明的支持,這一樣式被稱作“@AspectJ”樣式。這樣,就可以通過普通的 Java 5 編譯器編譯 AspectJ 應用程序,然后再由 AspectJ 編織器對其進行編織。作為例子,我們沒有使用常規代碼樣式語法中的 pointcut
關鍵字,而是定義了一個普通的 Java 方法,然后在定義切入點的方法上附加一個 Java 5 注釋。圖 9 顯示了這樣的一個示例??梢钥吹?,不管使用的開發樣式如何,AJDT 仍然顯示了應用程序的橫切結構。
![]() |
|
從 AJDT 1.1 遷移
考慮到 AJDT 1.2 和 1.3 中的變化的范圍,以及大量的內部重構,把原來采用 AJDT 1.1 Eclipse 工作空間升級會是一個相當復雜的過程,可能并不讓人驚訝。但是 AJDT 開發團隊已經通過引入遷移向導使這一過程盡可能的順利,如圖 10 所示。在升級 AJDT 版本之后,第一次運行 Eclipse 時會出現向導。在執行升級之前,應該打開想要包含在遷移過程中的項目,還應當關閉 AspectJ 編輯器的所有實例,因為 AspectJ 編輯器已經發生變化。(如果沒有關閉編輯器的實例,只會得到“cannot restore editor”錯誤,您可以放心地忽略這一錯誤。)
遷移向導的第一頁將根據需要對源文件的擴展名進行轉換,例如方面(以及任何包含切入點或內部方面的類)終止于 .aj 文件。如果需要,可以將項目排除在這個過程之外。請注意,在 AJDT 中,有一個轉換向導負責稍后根據需要對文件擴展名進行轉換;在單個項目或單個源文件上右擊可以找到這個向導。遷移向導的下一頁將指出,對于 Eclipse builder for AJDT 而言,哪一部分變化才是主要的內部變化。在這里,不能接受默認設置的惟一情況就是:想使用兼容性模式,讓項目仍然可以作為一個 AJDT 1.1 項目使用的時候。向導的第三頁只針對那些啟用了 AspectJ 的插件項目:對大型的 org.aspectj.ajde 插件不再存在運行時依賴,現在依賴的是新的、非常小的 org.aspectj.runtime 插件。下一頁將取消 AJDT 1.1 所做的所有全局工作空間設置,最后一頁將引入新的 Cross References 視圖。
![]() |
|
AJDT 開發注意事項
近一年以來,我們 AJDT 項目團隊一直使用 AspectJ 和 AJDT 開發 AJDT。AJDT 是由數量不斷增長的啟用 AspectJ 的插件實現的。由于許多開發人員已經在更大型的項目(大約有了 200,000 行代碼)中使用了 AJDT,所以 AJDT 經歷了合理的測試(除了大量 JUnit 測試和手工測試場景之外),這意味著我們能夠在您遭遇大量問題之前發現和修補它們。
使用 AOP (具體地說是 AspectJ 和 AJDT) 開發 AJDT 并將它與 Eclipse 集成,幫助我們把重點放在最需要的修補和增強上:最初,我們的生產率可能因轉換而降低,但是現在,我們的經驗讓我們更加感謝 AJDT 和 AspectJ 的增強。
完全出于這些原因,轉換是值得進行,當然,我們也期望同時從 AOP 得到一些好處!剛開始時,通過利用方面捕捉異常和向 Eclipse 的錯誤日志寫入適當條目,我們提高了診斷問題的能力 —— 在此之前,我們得手工異常處理,在應當處理異常的地方,有一半的地方遺漏了!我們還可以啟用一個監視方面,它將填充一個視圖,在 Visualiser 中顯示各種性能和資源使用測量情況。方面也可以用在 AJDT 中,強制實施編碼標準,跟蹤對多個屬性頁的變化,以及用 Eclipse 的 ISafeRunnable
接口包裝調用。最好的消息可能是:所有這些都僅僅是開始,在不遠的未來,我們期望讓方面變成 AJDT 新功能設計的基本部分。
![]() |
|
AJDT 的未來
如果您熟悉 AJDT 早期的版本,那么您現在可能已經看到在 AJDT 1.2 和 1.3 中很多東西都已經發生了變化?,F在回到 AJDT 1.1,AspectJ 編輯器能力很弱,但卻既可以用于編輯類,也可以用于編輯方面,定制的大綱視圖比標準 Java 大綱視圖要弱一些。對比之下,新的 AspectJ 編輯器為編輯方面提供了更豐富的體驗,用標準的 Java 編輯器編輯類,標準的大綱視圖得到增強,現在可以支持方面。這也意味著用參數配置向導對工作空間進行全局設置修改不再是必需的。
關系到 ajdoc 的生成的功能以及對構建配置的支持在很大程度上并沒有發生改變,但是大多數領域都得到了改進和擴展?,F在有一些顯示和導航程序的橫切結構的新方法,還有一些對導出到 JAR 文件、轉換文件擴展名和創建構建文件的新支持,以及對遞增編譯(現在是默認設置)以及處理更大項目的更靈活的 Visualiser 的明顯支持。文檔已經被徹底革新,以幫助您從 AJDT 得到最大好處。
盡管有這些進展,仍然有許多事要做。首先,是與 Eclipse 的集成問題:從長遠來看,健壯的、全面集成的 AJDT 要求 Eclipse 中的 Java 工具要比目前更具擴展性,我們希望我們開發 AJDT 的經驗能在這一領域有所貢獻。其次,我們總有更多特性可以開發,以增強 AspectJ 的工具。這些包括面向方面的重構、對開發和使用方面庫的增強支持,以及開發更多處理“信息過載”的方法 —— 例如在項目中增加對 AspectJ 的使用時,會造成過量的橫切標記。AJDT 仍然由用戶需求驅動,所以請告訴我們您需要哪些功能,哪些 bug 給您帶來了最大問題。如果您想參與其中,請定位到 AJDT 的主頁(參閱 參考資料),查看 Bugzilla 的鏈接、新聞組、開發人員郵件列表和 to-do 任務頁面。