劉旭斌,朱國賓,關培超,朱鑫偉
(1.武漢大學 國際軟件學院,湖北 武漢 430079;2.武漢大學 測繪遙感信息工程國家重點實驗室,湖北 武漢 430079)
在地理信息服務平臺中,用戶可瀏覽、發布以及使用各種地理服務,而管理員則需對用戶行為進行審批管理。在Web服務進程中,為了進行錯誤追蹤、分析用戶行為,以便更好地提供服務,需對用戶行為進行日志記錄。
一個常規的Web 應用系統,一般會涉及系統業務相關的模塊和分布在這些模塊中的公共行為(如數據庫事務處理、安全性、日志處理、權限控制、例外處理等)[1]。我們通常把前者稱為核心關注點,后者因其“貫穿性”的特點稱為橫切關注點[1]。在地理信息服務平臺中,OOP可以很方便地將其中的“名詞”(如服務、用戶等)映射為Java系統中的對象,這樣更加貼近日常的思維方式,便于理解。即采用OOP處理核心關注點時,可以提高建模的效率。但由于橫切關注點(如日志記錄)幾乎涉及到系統中的各個對象,如果采用OOP直接編碼的方式,這些代碼會分散在各個對象代碼中,造成大量冗余,使得系統的核心業務邏輯模塊與輔助模塊耦合性較高。這樣不僅會造成代碼分散、混亂的問題,而且不便于后期維護和管理。此時OOP的傳統優勢不僅不能得到充分的發揮,反而成為影響代碼簡潔高效維護的障礙。而AOP則可以有效地解決這一問題。
AOP是對OOP技術的一種補充。OOP 把應用分解成帶有層次結構的對象,而AOP把程序分解成為一些切面或關注點[2],它允許程序員對橫切性的問題(Crosscutting Concerns——跨越典型職責界線的行為,例如事務處理、權限控制等)進行模塊化[2],開發由原來的一維模式變為了二維模式,提高了應用系統開發維護的效率。AOP 就其本質而言,是用一種松散耦合的方式來實現獨立的關注點,并組合這些關注點來實現最終系統[3],它很好地彌補了OOP和EJB的不足,可使地理信息服務平臺的開發變得更加簡潔高效易維護,代碼重用性也得到了極大的提高。
AOP的概念是由施樂Palo Alto 研究中心的Gregor Kiczales于1977年提出的。由于OOP無法解決切面和業務核心邏輯模塊形成橫切,從而造成代碼糾結問題。為此,研究者提出了一種新的AOP編程思想,解決了面向對象方法在非功能單元橫向管理存在的缺陷,提供了一種明確捕獲和模塊化橫切關注點(日志、事務、權限認證等)的機制[4],提高了系統的可擴展性,實現調用者和被調用者之間的充分解耦[5]。而切面、連接點、切入點、通知等機制是AOP的核心所在。切面是實現橫切關注點的模塊,連接點是切面將會被植入的點,切入點是一個或多個連接點的集合,通知則是在切入點將要執行的邏輯代碼。
AOP的核心思想是將與系統核心業務邏輯無關的系統橫切關注點(如數據庫事務處理、安全性檢查、日志記錄等)抽取出來,單獨對其進行建模、設計、實現,以提高系統程序的抽象性和模塊化程度,改善軟件的可復用性、可擴展性和可維護性。如圖1所示,從遺留系統中分別抽取出核心業務邏輯模塊和日志、事務等橫切關注點,然后使用面向對象編程的思想實現業務邏輯方法,將模塊化后的切面切入到業務邏輯方法前后,使其由原來的面向對象的一維空間實現,變成現在的二維空間實現。也就是說,原來的事務處理、日志等功能的實現被限制在每一個需要調用它的模塊中,而現在這些模塊只需專注實現自己的業務功能即可,從而避免了代碼的分散和混亂,提高了代碼的重用性。

自AOP提出以后,經過多年的深入研究,市場上已經出現了成熟度較高的AOP工具,如AspectJ、JBoss、Spring AOP等。但各種工具關注面不同,實現機制也有所區別,導致風格各異,適用場合也不同。本文將集中探討AspectJ和Spring AOP的異同,并從多個角度比較它們的特征以及適用情況。
需要明確的是,不論哪一種工具,其設計目標都是將橫切的切面問題模塊化。因此,切入點就是AOP的核心。此外,AOP工具還提供了類型間聲明和通知機制。3者的組合,構成了切面。不同AOP工具的主要區別在于切面聲明的方式以及如何應用到系統中。
1) AspectJ的切面聲明類似于Java語言中的類聲明,是基于Java語言的語法及語義的擴展。它擁有屬于自身的基于Java平臺的AOP語法、AspectJ編譯器以及啟動器。
2)Spring AOP實現切面聲明的方式包括基于XML方式、@AspectJ注解方式等。Spring AOP不需要獨立的啟動器,因為它依賴的是 Spring 框架方便的、最小化的運行配置。
AspectJ由Java語言擴展而來,屬于代碼級,在處理新建項目時可以考慮使用,而在處理遺留系統中則不太適合,因為可能會大量修改源代碼。Spring AOP提供的XML風格切面聲明在修改切入點時只需在XML配置文件中進行修改,更加簡潔方便。表1詳細對比了2種方式的特征。

表1 2種實現方式特征對比
和大多數Web項目一樣,本文介紹的地理信息服務平臺中的日志系統要求不是特別精細,只需使用輕量級的Spring AOP即可滿足需求。而對于其他項目,若是遺留系統,需添加日志模塊,則選擇Spring AOP更加合適,它可以在不修改源代碼的基礎上將日志模塊整合進去,而AspectJ則更適合用在粒度級要求更加精細的系統中。
本文介紹的地理信息服務平臺旨在為用戶提供一個發布共享各種地理服務的平臺,用戶也可申請使用其他用戶共享的服務。在該平臺中,普通用戶的注冊、服務發布及使用等申請,以及管理員審批動作,均需記錄在日志系統中。但在開發中,日志輸出分散在各個模塊,且在許多源文件中相互糾結,使得系統的相關復雜度較高,不利于后期的改進及維護。因此,我們將采用AOP解決方案,以期降低相關復雜度,使系統變得簡單可靠,便于維護。
此系統的業務邏輯是用戶可通過平臺瀏覽新聞、申請注冊賬號、申請發布服務、申請使用服務,管理員可通過平臺發布新聞以及對用戶申請進行審批,而日志系統負責記錄下這些動作,前者的執行會引發后者的執行,并將數據等信息傳遞給后者,以便準確記錄。
為了測試AOP方式解決方案的優勢,設計了基于OOP的解決方案進行對比。
方案一:僅OOP實現,見圖2。

方案二:OOP與AOP結合實現,見圖3。

OOP+AOP實現圖方案二在方案一的基礎上,將代碼中日志記錄獨立出來成為一個模塊,通過AOP配置文件,實現自動攔截切點(原理見圖4)和日志輸出功能。

與方案一相比,方案二更易降低每個模塊的復雜度,提高模塊的可靠性,使得代碼更為簡單。如果我們把OOP看作從上到下的軟件開發過程,那么AOP則是從左到右的軟件開發過程[6],即從面向對象的一維思考方式轉變成二維空間的實現[7]。
使用方案二方式實現地理信息服務平臺時,其中的日志記錄按緊急程度分為debug、info、warning、err、引用emerg 5個level級別,其中,debug為不包含函數條件或問題的其他信息;info為提供信息的消息 ;warning為預警信息;err為阻止工具或某些子系統部分功能實現的錯誤條件;引用emerg為該系統不可用。而本平臺日志系統需記錄的為一般消息(即用戶和管理員的操作),所以選擇使用info級別記錄相應的日志。日志系統的邏輯架構如圖5所示。

實現時,我們需要找到切面相應的連接點。在UserApproveDao.java類中,針對具體的用戶注冊申請、管理員審批及刪除注冊申請的動作,找到對應的方法addUserApprove( )、Approve( )、delUserApprove( ), 即為連接點JoinPoint。
通知Advice的實現是通過記錄日志的方法log_AOP(JoinPoint joinPoint, Object returnValue)完成的。
Java代碼(部分):
public void log_AOP(JoinPoint joinPoint, Object returnValue) {
if(join Point.get Signa ture().get Name().equals("addUserApprove")) {
String userId = (String) joinPoint.getArgs()[0];
syslog.info(logFormat.format(..);
}
//后續動作
}
最后,需要配置系統的配置文件applicationContext.xml。
Xml代碼(部分):
pointcut-ref="pointCut_0" returning="returnValue" /> 在比較OOP和AOP兩種方案時,采用相同的測試條件: 1)硬件配置:ubuntu服務器;蘋果Mac(4 G內存,CPU 2.66 GHz雙核); 2)軟件支持平臺:Windows7(64位), myeclipse 10.5, syslog-ng_3.3.1; 3)測試案例:2n(n=1,2,3,…,13)個線程同時向日志服務器寫日志; 4)前提條件:網絡穩定,局域網100 MB帶寬; 5)預期結果:在線程數較少的情況下,2種方式的耗時相差不大。但隨著線程數指數級遞增,2種方式的耗時也逐漸增大,AOP方式的耗時會比傳統編碼方式的耗時長,且2者的差距越來越大。 測試結果如表2、表3所示。 表2 傳統直接編碼方式 表3 AOP方式 測試和對比(見圖6)表明,在線程數較少時,兩者的差別不大,甚至基于AOP的實現所耗時間系統性地低于基于OOP的實現方式。但隨著線程數指數級的遞增,AOP方式的耗時比傳統編碼方式的耗時長,且差距越來越大。但在實用情況下,如果考慮1 024個并發數量是合理的系統指標時,這部分額外增加的時間仍在可以接受的范圍之類。進一步考慮到AOP方式實現可以降低模塊之間的耦合性,避免代碼分散和混亂,在代碼量方面可以縮減很多,而且降低了整個項目的復雜度,所以在具體Java Web項目開發中,如果對運行時間要求不是特別苛刻的話,恰當地使用AOP可以提高開發效率。 作為OOP思想的補充,AOP在軟件開發中扮演著越來越重要的角色。從提出到現在,AOP的研發是迅速的,且慢慢趨向于成熟。它不是一種取代OOP的技術,而是與OOP相互補充,它解決了OOP中橫切關注面分散在核心業務邏輯代碼中,無法進行模塊化的問題。在未來的項目開發中,AOP將作為一種不可或缺的編程思想,滲透在各個應用領域。 [1]Sharwood S. A New Aspect to Programming?[EB/OL].http://www.techrepublic.com/article/a-new-aspect-toprogramming,2005-04-08 [2]O’Regan G. Introduction to Aspect-Oriented Programming[EB/OL]. http://www.onjava.com./pub/a/onjava/2004/01/14/aop.html,2004-01-14 [3]Johnson R, Juergen Hoeller.Expert One-on-One J2EE Development without EJB[M].Indianapolis, Indiana: Wiley Publishing,Inc,2004 [4]孟凡新,張京軍,劉光遠.基于AOP和WEB服務的多層分布式系統[J].計算機工程,2010,36 (1):61-63 [5]肖榮,張云華.基于AOP 和反射計算的動態適應中間件[J].計算機系統應用,2010,9(1):58-62 [6]駱四毛,周興斌.AOP對軟件復雜度的影響分析及應用[J].計算機工程與設計,2013,34(5):1 822-1 825 [7]肖露,龍鵬飛.基于JAVA的動態代理實現的AOP的研究[J].微計算機信息,2011,27(2):211-213


4 結 語