一、AOP編程概覽
面向對象編程技術進入軟件開發的主流對軟件的開發方式產生了極大的影響,開發者可以用一組實體以及這些實體之間的關系將系統形象地表示出來,這使得他們能夠設計出規模更大、更復雜的系統,開發周期也比以前更短。OO開發的唯一問題是,它本質上是靜態的,需求的細微變化就可能對開發進度造成重大影響。
Aspect-Oriented Programming(AOP)是對OO技術的補充和完善,它允許開發者動態地修改靜態的OO模型,構造出一個能夠不斷增長以滿足新增需求的系統,就象現實世界中的對象會在其生命周期中不斷改變自身,應用程序也可以在發展中擁有新的功能。
例如,許多人想必有過在開發簡單的Web應用時將Servlet作為入口點的經驗,即用Servlet接收HTML表單的輸入,經過處理後返回給用戶。開始時的Servlet可能是非常簡單的,只有剛好滿足用戶需求的最少量的代碼。然而,隨著“第二需求”的實現,例如實現異常處理、安全、日志等功能,代碼的體積就會增加到原來的三、四倍——之所以稱之為“第二需求”,是因為Servlet的基本功能是接受和處理用戶的請求,對於這個目標來說,日志、安全之類的機制並不是必不可少的。
AOP允許動態地改變OO的靜態模型,不必修改原來的靜態模型也可以加入滿足第二需求所需的代碼(實際上,甚至連原來的源代碼也不需要)。更令人稱奇的是,後來加入的代碼往往可以集中在一個地方,而不必象單純使用OO時那樣將後來加入的代碼分散到整個模型。
二、基本術語
在介紹AOP開發實例之前,我們先來了解幾個標准的AOP術語,以便更好地掌握相關的概念。
Cross-cutting concern
在OO模型中,雖然大部份的類只有單一的、特定的功能,但它們通常會與其他類有著共同的第二需求。例如,當線程進入或離開某個方法時,我們可能既要在數據訪問層的類中記錄日志,又要在UI層的類中記錄日志。雖然每個類的基本功能極然不同,但用來滿足第二需求的代碼卻基本相同。
Advice
它是指想要應用到現有模型的附加代碼。在本例中,它是指線程進入或退出某個方法時要運行的日志代碼。
Point-cut
這個術語是指應用程序中的一個執行點,在這個執行點上需要采用前面的cross-cutting concern。在本例中,當線程進入一個方法時出現一個Point-cut,當線程離開方法時又出現另一個Point-cut。
Aspect
Point-cut和advice結合在一起就叫做aspect。在下面的例子中,我們通過定義一個point-cut並給予適當的advice加入了一個日志(logging)aspect。
AOP還有其它許多特性和術語,例如引入(Introduction),即把接口/方法/域引入到現有的類——它極大地拓寬了開發者的想象力。不過本文只介紹一些最基本的持性,熟悉這裡介紹的概念後,你再深入一步研究AOP的其它特性,看看如何在自己的開發環境中使用它們。
三、現有的框架
目前最成熟、功能最豐富的AOP框架當數AspectJ,AspectJ已成為大多數其它框架跟從的標准。但是,AspectJ也走出了非同尋常的一步,它的實現為Java語言增添了新的關鍵詞。雖然新的語法並不難學,但卻意味著我們必須換一個編譯器,還要重新配制編輯器,只有這樣才能適應新的語法。在規模較大的開發組中,這些要求可能難以辦到,因為整個開發小組都會受到影響。由於語言本身的變化,開發小組把AOP技術引入到現有項目的學習周期隨之延長。
現在我們需要的是這樣一個框架,它可以方便地引入,且不會對原來的開發和構造過程產生任何影響。滿足這些要求的框架不止一個,例如JBoss AOP、Nanning、Aspectwerkz(AW)。本文選用的是Aspectwerkz,因為它可能是最容易學習的框架,也是最容易集成到現有項目的框架。
Aspectwerkz由Jonas Boner和Alexandre Vasseur創建,它是目前最快速、功能最豐富的框架之一。雖然它還缺乏AspectJ的某些功能,但己足以滿足大多數開發者在許多情形下的需要。
Aspectwerkz最令人感興趣的特性之一是它能夠以兩種不同的模式運行:聯機模式和脫機模式。在聯機模式下,AW直接干預屬於JVM的底層類裝入機制,截取所有的類裝入請求,對字節碼實施即時轉換。AW提供了干預類裝入過程的許多選項,另外還有一個替代bin/java命令的封裝腳本,這個腳本能夠根據Java版本和JVM能力自動生成一組可運行的配制。對於開發者,聯機模式有許多優點,它能插入到任何類裝入器並在類裝入期間生成新的類。也就是說,我們不必手工修改應用程序的類,只要按通常的方式部署即可。不過,聯機模式要求對應用服務器進行額外的配制,有時這一要求可能很難滿足。
在脫機模式下,生成類需要二個步驟。第一步是用標准的編譯器編譯,第二步是重點——以脫機模式運行AWcompiler編譯器,讓它處理新生成的類。編譯器將修改這些類的字節碼,根據一個XML文件的定義,在適當的point-cut插入advice。脫機模式的優點是AWcompiler生成的類能夠在任何JVM 1.3以上的虛擬機運行,本文下面要用的就是這種模式,因為它不需要對Tomcat作任何修改,只要對構造過程稍作修改就可以照搬到大多數現有的項目。