劉旭斌,朱國賓,關(guān)培超,朱鑫偉
(1.武漢大學(xué) 國際軟件學(xué)院,湖北 武漢 430079;2.武漢大學(xué) 測繪遙感信息工程國家重點實驗室,湖北 武漢 430079)
在地理信息服務(wù)平臺中,用戶可瀏覽、發(fā)布以及使用各種地理服務(wù),而管理員則需對用戶行為進(jìn)行審批管理。在Web服務(wù)進(jìn)程中,為了進(jìn)行錯誤追蹤、分析用戶行為,以便更好地提供服務(wù),需對用戶行為進(jìn)行日志記錄。
一個常規(guī)的Web 應(yīng)用系統(tǒng),一般會涉及系統(tǒng)業(yè)務(wù)相關(guān)的模塊和分布在這些模塊中的公共行為(如數(shù)據(jù)庫事務(wù)處理、安全性、日志處理、權(quán)限控制、例外處理等)[1]。我們通常把前者稱為核心關(guān)注點,后者因其“貫穿性”的特點稱為橫切關(guān)注點[1]。在地理信息服務(wù)平臺中,OOP可以很方便地將其中的“名詞”(如服務(wù)、用戶等)映射為Java系統(tǒng)中的對象,這樣更加貼近日常的思維方式,便于理解。即采用OOP處理核心關(guān)注點時,可以提高建模的效率。但由于橫切關(guān)注點(如日志記錄)幾乎涉及到系統(tǒng)中的各個對象,如果采用OOP直接編碼的方式,這些代碼會分散在各個對象代碼中,造成大量冗余,使得系統(tǒng)的核心業(yè)務(wù)邏輯模塊與輔助模塊耦合性較高。這樣不僅會造成代碼分散、混亂的問題,而且不便于后期維護(hù)和管理。此時OOP的傳統(tǒng)優(yōu)勢不僅不能得到充分的發(fā)揮,反而成為影響代碼簡潔高效維護(hù)的障礙。而AOP則可以有效地解決這一問題。
AOP是對OOP技術(shù)的一種補(bǔ)充。OOP 把應(yīng)用分解成帶有層次結(jié)構(gòu)的對象,而AOP把程序分解成為一些切面或關(guān)注點[2],它允許程序員對橫切性的問題(Crosscutting Concerns——跨越典型職責(zé)界線的行為,例如事務(wù)處理、權(quán)限控制等)進(jìn)行模塊化[2],開發(fā)由原來的一維模式變?yōu)榱硕S模式,提高了應(yīng)用系統(tǒng)開發(fā)維護(hù)的效率。AOP 就其本質(zhì)而言,是用一種松散耦合的方式來實現(xiàn)獨立的關(guān)注點,并組合這些關(guān)注點來實現(xiàn)最終系統(tǒng)[3],它很好地彌補(bǔ)了OOP和EJB的不足,可使地理信息服務(wù)平臺的開發(fā)變得更加簡潔高效易維護(hù),代碼重用性也得到了極大的提高。
AOP的概念是由施樂Palo Alto 研究中心的Gregor Kiczales于1977年提出的。由于OOP無法解決切面和業(yè)務(wù)核心邏輯模塊形成橫切,從而造成代碼糾結(jié)問題。為此,研究者提出了一種新的AOP編程思想,解決了面向?qū)ο蠓椒ㄔ诜枪δ軉卧獧M向管理存在的缺陷,提供了一種明確捕獲和模塊化橫切關(guān)注點(日志、事務(wù)、權(quán)限認(rèn)證等)的機(jī)制[4],提高了系統(tǒng)的可擴(kuò)展性,實現(xiàn)調(diào)用者和被調(diào)用者之間的充分解耦[5]。而切面、連接點、切入點、通知等機(jī)制是AOP的核心所在。切面是實現(xiàn)橫切關(guān)注點的模塊,連接點是切面將會被植入的點,切入點是一個或多個連接點的集合,通知則是在切入點將要執(zhí)行的邏輯代碼。
AOP的核心思想是將與系統(tǒng)核心業(yè)務(wù)邏輯無關(guān)的系統(tǒng)橫切關(guān)注點(如數(shù)據(jù)庫事務(wù)處理、安全性檢查、日志記錄等)抽取出來,單獨對其進(jìn)行建模、設(shè)計、實現(xiàn),以提高系統(tǒng)程序的抽象性和模塊化程度,改善軟件的可復(fù)用性、可擴(kuò)展性和可維護(hù)性。如圖1所示,從遺留系統(tǒng)中分別抽取出核心業(yè)務(wù)邏輯模塊和日志、事務(wù)等橫切關(guān)注點,然后使用面向?qū)ο缶幊痰乃枷雽崿F(xiàn)業(yè)務(wù)邏輯方法,將模塊化后的切面切入到業(yè)務(wù)邏輯方法前后,使其由原來的面向?qū)ο蟮囊痪S空間實現(xiàn),變成現(xiàn)在的二維空間實現(xiàn)。也就是說,原來的事務(wù)處理、日志等功能的實現(xiàn)被限制在每一個需要調(diào)用它的模塊中,而現(xiàn)在這些模塊只需專注實現(xiàn)自己的業(yè)務(wù)功能即可,從而避免了代碼的分散和混亂,提高了代碼的重用性。
自AOP提出以后,經(jīng)過多年的深入研究,市場上已經(jīng)出現(xiàn)了成熟度較高的AOP工具,如AspectJ、JBoss、Spring AOP等。但各種工具關(guān)注面不同,實現(xiàn)機(jī)制也有所區(qū)別,導(dǎo)致風(fēng)格各異,適用場合也不同。本文將集中探討AspectJ和Spring AOP的異同,并從多個角度比較它們的特征以及適用情況。
需要明確的是,不論哪一種工具,其設(shè)計目標(biāo)都是將橫切的切面問題模塊化。因此,切入點就是AOP的核心。此外,AOP工具還提供了類型間聲明和通知機(jī)制。3者的組合,構(gòu)成了切面。不同AOP工具的主要區(qū)別在于切面聲明的方式以及如何應(yīng)用到系統(tǒng)中。
1) AspectJ的切面聲明類似于Java語言中的類聲明,是基于Java語言的語法及語義的擴(kuò)展。它擁有屬于自身的基于Java平臺的AOP語法、AspectJ編譯器以及啟動器。
2)Spring AOP實現(xiàn)切面聲明的方式包括基于XML方式、@AspectJ注解方式等。Spring AOP不需要獨立的啟動器,因為它依賴的是 Spring 框架方便的、最小化的運行配置。
AspectJ由Java語言擴(kuò)展而來,屬于代碼級,在處理新建項目時可以考慮使用,而在處理遺留系統(tǒng)中則不太適合,因為可能會大量修改源代碼。Spring AOP提供的XML風(fēng)格切面聲明在修改切入點時只需在XML配置文件中進(jìn)行修改,更加簡潔方便。表1詳細(xì)對比了2種方式的特征。
表1 2種實現(xiàn)方式特征對比
和大多數(shù)Web項目一樣,本文介紹的地理信息服務(wù)平臺中的日志系統(tǒng)要求不是特別精細(xì),只需使用輕量級的Spring AOP即可滿足需求。而對于其他項目,若是遺留系統(tǒng),需添加日志模塊,則選擇Spring AOP更加合適,它可以在不修改源代碼的基礎(chǔ)上將日志模塊整合進(jìn)去,而AspectJ則更適合用在粒度級要求更加精細(xì)的系統(tǒng)中。
本文介紹的地理信息服務(wù)平臺旨在為用戶提供一個發(fā)布共享各種地理服務(wù)的平臺,用戶也可申請使用其他用戶共享的服務(wù)。在該平臺中,普通用戶的注冊、服務(wù)發(fā)布及使用等申請,以及管理員審批動作,均需記錄在日志系統(tǒng)中。但在開發(fā)中,日志輸出分散在各個模塊,且在許多源文件中相互糾結(jié),使得系統(tǒng)的相關(guān)復(fù)雜度較高,不利于后期的改進(jìn)及維護(hù)。因此,我們將采用AOP解決方案,以期降低相關(guān)復(fù)雜度,使系統(tǒng)變得簡單可靠,便于維護(hù)。
此系統(tǒng)的業(yè)務(wù)邏輯是用戶可通過平臺瀏覽新聞、申請注冊賬號、申請發(fā)布服務(wù)、申請使用服務(wù),管理員可通過平臺發(fā)布新聞以及對用戶申請進(jìn)行審批,而日志系統(tǒng)負(fù)責(zé)記錄下這些動作,前者的執(zhí)行會引發(fā)后者的執(zhí)行,并將數(shù)據(jù)等信息傳遞給后者,以便準(zhǔn)確記錄。
為了測試AOP方式解決方案的優(yōu)勢,設(shè)計了基于OOP的解決方案進(jìn)行對比。
方案一:僅OOP實現(xiàn),見圖2。
方案二:OOP與AOP結(jié)合實現(xiàn),見圖3。
OOP+AOP實現(xiàn)圖方案二在方案一的基礎(chǔ)上,將代碼中日志記錄獨立出來成為一個模塊,通過AOP配置文件,實現(xiàn)自動攔截切點(原理見圖4)和日志輸出功能。
與方案一相比,方案二更易降低每個模塊的復(fù)雜度,提高模塊的可靠性,使得代碼更為簡單。如果我們把OOP看作從上到下的軟件開發(fā)過程,那么AOP則是從左到右的軟件開發(fā)過程[6],即從面向?qū)ο蟮囊痪S思考方式轉(zhuǎn)變成二維空間的實現(xiàn)[7]。
使用方案二方式實現(xiàn)地理信息服務(wù)平臺時,其中的日志記錄按緊急程度分為debug、info、warning、err、引用emerg 5個level級別,其中,debug為不包含函數(shù)條件或問題的其他信息;info為提供信息的消息 ;warning為預(yù)警信息;err為阻止工具或某些子系統(tǒng)部分功能實現(xiàn)的錯誤條件;引用emerg為該系統(tǒng)不可用。而本平臺日志系統(tǒng)需記錄的為一般消息(即用戶和管理員的操作),所以選擇使用info級別記錄相應(yīng)的日志。日志系統(tǒng)的邏輯架構(gòu)如圖5所示。
實現(xiàn)時,我們需要找到切面相應(yīng)的連接點。在UserApproveDao.java類中,針對具體的用戶注冊申請、管理員審批及刪除注冊申請的動作,找到對應(yīng)的方法addUserApprove( )、Approve( )、delUserApprove( ), 即為連接點JoinPoint。
通知Advice的實現(xiàn)是通過記錄日志的方法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(..);
}
//后續(xù)動作
}
最后,需要配置系統(tǒng)的配置文件applicationContext.xml。
Xml代碼(部分):
pointcut-ref="pointCut_0" returning="returnValue" /> 在比較OOP和AOP兩種方案時,采用相同的測試條件: 1)硬件配置:ubuntu服務(wù)器;蘋果Mac(4 G內(nèi)存,CPU 2.66 GHz雙核); 2)軟件支持平臺:Windows7(64位), myeclipse 10.5, syslog-ng_3.3.1; 3)測試案例:2n(n=1,2,3,…,13)個線程同時向日志服務(wù)器寫日志; 4)前提條件:網(wǎng)絡(luò)穩(wěn)定,局域網(wǎng)100 MB帶寬; 5)預(yù)期結(jié)果:在線程數(shù)較少的情況下,2種方式的耗時相差不大。但隨著線程數(shù)指數(shù)級遞增,2種方式的耗時也逐漸增大,AOP方式的耗時會比傳統(tǒng)編碼方式的耗時長,且2者的差距越來越大。 測試結(jié)果如表2、表3所示。 表2 傳統(tǒng)直接編碼方式 表3 AOP方式 測試和對比(見圖6)表明,在線程數(shù)較少時,兩者的差別不大,甚至基于AOP的實現(xiàn)所耗時間系統(tǒng)性地低于基于OOP的實現(xiàn)方式。但隨著線程數(shù)指數(shù)級的遞增,AOP方式的耗時比傳統(tǒng)編碼方式的耗時長,且差距越來越大。但在實用情況下,如果考慮1 024個并發(fā)數(shù)量是合理的系統(tǒng)指標(biāo)時,這部分額外增加的時間仍在可以接受的范圍之類。進(jìn)一步考慮到AOP方式實現(xiàn)可以降低模塊之間的耦合性,避免代碼分散和混亂,在代碼量方面可以縮減很多,而且降低了整個項目的復(fù)雜度,所以在具體Java Web項目開發(fā)中,如果對運行時間要求不是特別苛刻的話,恰當(dāng)?shù)厥褂肁OP可以提高開發(fā)效率。 作為OOP思想的補(bǔ)充,AOP在軟件開發(fā)中扮演著越來越重要的角色。從提出到現(xiàn)在,AOP的研發(fā)是迅速的,且慢慢趨向于成熟。它不是一種取代OOP的技術(shù),而是與OOP相互補(bǔ)充,它解決了OOP中橫切關(guān)注面分散在核心業(yè)務(wù)邏輯代碼中,無法進(jìn)行模塊化的問題。在未來的項目開發(fā)中,AOP將作為一種不可或缺的編程思想,滲透在各個應(yīng)用領(lǐng)域。 [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]孟凡新,張京軍,劉光遠(yuǎn).基于AOP和WEB服務(wù)的多層分布式系統(tǒng)[J].計算機(jī)工程,2010,36 (1):61-63 [5]肖榮,張云華.基于AOP 和反射計算的動態(tài)適應(yīng)中間件[J].計算機(jī)系統(tǒng)應(yīng)用,2010,9(1):58-62 [6]駱?biāo)拿?周興斌.AOP對軟件復(fù)雜度的影響分析及應(yīng)用[J].計算機(jī)工程與設(shè)計,2013,34(5):1 822-1 825 [7]肖露,龍鵬飛.基于JAVA的動態(tài)代理實現(xiàn)的AOP的研究[J].微計算機(jī)信息,2011,27(2):211-2134 結(jié) 語