面向方面編程(aspect-Oriented PRogramming,AOP)正在軟件社區和企業界中獲得強大的發展動力。自從20世紀90年代Xerox引入了AOP之后,AOP經過研究團體、開源社區和企業界的數次推動和革新,已經越來越成熟了。在java領域,近兩年開源運動已經獲得了極大的推動,這導致AspectWerkz和AspectJ最近合并在一起,現在它們都歸入Eclipse Foundation,代號為AspectJ 5。AspectJ是由BEA Systems公司和IBM公司發起的,可以認為它是使用Java實現AOP的事實標準。
隨著AOP流行程度的逐漸增加和研究團體的不懈努力,詞匯表、概念和實現已經趨于一致,這得到了更完善的工具支持,答應更好的開發者體驗,比如,出現了AspectJ Eclipse插件AspectJ Development Tools (AJDT)。
AOP已經經歷了多種實現技術,從源代碼操作到字節碼測試(這是Java中一種廣泛采用的技術,非凡是在Java 5 JVMTI出現之后)。如今,在應用程序治理和監視領域,有多種應用AOP的企業級產品采用了這種技術,并且最近隨著基于POJO(Plain Old Java Object)的中間件和透明集群的出現而變得越來越流行。
因此,無論如何,字節碼測試越來越可能成為你最終必須把握的東西。你將不得不回答下面這些問題:字節碼測試技術究竟能夠把可治理性、透明性和效率擴展和實現到什么程度?依靠于字節碼測試的AOP實現會不會發展到盡頭,以至無法為更高的效率、易用性和動態性做進一步的革新?JVM對AOP的支持會解決這些問題嗎?能夠解決到什么程度?本系列文章通過揭示BEA JRockit JVM AOP支持的內幕以及激發在這個領域中的爭論,來提供這些問題的具體答案。
第一篇文章介紹AOP概念并且簡單地說明為什么許多實現(比如AspectJ)要基于字節碼操作。它解釋了與字節碼測試技術相關的一些限制,以及它們為什么會在長期運行過程中影響可伸縮性和可用性。然后,最后一節介紹JRockit JVM對AOP的支持,這一技術的目標是克服這些限制,為AOP和其他截取機制提供一個高效率的后端。
本系列文章的第2部分將通過具體的API細節和示例來說明這種支持的力度。
什么是面向方面編程?
面向對象的分析和設計引入了繼續、抽象和多態等概念,由此為我們提供了降低軟件復雜性的工具。但是,開發人員在軟件設計過程中仍然經常會面對無法用面向對象軟件開發技術輕易解決的問題。這些問題之一就是如何處理應用程序中的橫切關注點(Cross-cutting concerns)。
橫切關注點
關注點就是設計人員感愛好的某一概念或區域。例如,在一個訂貨系統中,核心關注點可能是訂單處理和生產,而系統關注點可能是事務處理和安全治理。
橫切關注點是影響多個類或模塊的關注點,即未能很好地局部化和模塊化的關注點。
橫切關注點的表現有:
·代碼糾結——當一個模塊或代碼段同時治理多個關注點時發生這種情況。
·代碼分散——當一個關注點分布在許多模塊中并且未能很好地局部化和模塊化時發生這種情況。
這些現象會從幾個方面影響軟件;例如,它們會導致軟件難以維護和重用,并且難以編寫和理解。
關注點的隔離
面向方面編程試圖通過引入“關注點的隔離”這一概念來解決這些問題。采用這一概念,可以以一種模塊化而且適當局部化的方式實現關注點。AOP解決這個問題的辦法是在設計空間中增加額外一維,并且引入了一些構造,這些構造使我們能夠定義橫切關注點,將它們轉移進新的維,并且以模塊化方式將它們打包。
AOP引入的新構造
AOP引入了一些新的構造。聯結點(join point)構造準確反映了程序流中定義良好的點,例如調用方法的地方或者捕捉異常的地方。切點(pointcut)構造使我們能夠挑選出匹配某一標準的聯結點。建議(advice)構造使我們能夠添加應該在匹配的聯結點執行的代碼。引入(introdUCtion)構造使我們能夠向現有的類添加額外的代碼,例如,向現有的類添加方法、字段或接口。最后,AOP引入了方面(aspect)構造,這是模塊化的AOP單元。方面由聯結點、切點、建議和引入來定義(也稱為類型間聲明)。
用AspectJ實現AOP的示例
下面是一些簡單的AspectJ 5代碼示例,它們在一定程度上說明了如何在代碼中實現上面定義的概念。要想進一步了解特定的AOP語言細節,請參考AspectJ文檔。
// using a dedicated syntax// that compliments the Java languagepublic aspect Foo { pointcut someListOperation() : call(* List+.add(..)); pointcut userScope() : within(com.biz..*); before() : someListOperation() && userScope() { System.out.println("called: " + thisJoinPoint.getSignature() ); }}以上代碼使用了一種專門的語法。可以使用Java注釋寫出等效的代碼。
// the Java 5 annotations approach@Aspectpublic class Foo { @Pointcut("call(* java.util.List+.add(..))") public void someListOperation() {} @Pointcut("within(com.biz..*)") public void userScope() {} @Before("someListOperation() && userScope()") public void before(JoinPoint thisJoinPoint) { System.out.println("called: " + thisJoinPoint.getSignature() ); }}新聞熱點
疑難解答