如果要做為一名合格的軟體架構師,AOP是必須知道的一門技術。那麼AOP是什麼呢,這就是今天所討論的內容(也是本人最近一陣子的學習總結,希望大家多多指點)。
AOP,全稱Aspect Oriented Programming,中文名稱叫面向方面編程,也叫面向切面編程。
在實際項目開發過程中,我們往往會注意到有一些模組/功能,如許可權,緩衝等,需要存在於軟體的各個業務模組中,而這些模組/功能又與業務模組沒有任何關係,甚至在設計業務模組時我們完全不用考慮這些模組/功能的存在,但是在開發過程中才發現這些模組/功能會給我們帶來無盡的煩惱。因為傳統的OOP方法考慮問題的出發點往往是要解決問題的本身和延伸,所以遇到此類情況時傳統的OOP方法就很難解決。然而對業務模組和此類別模組稍作分析,我們就會發現,其實它們本質是相同的,只是解決的問題不同,對一個軟體的關注點不同,如所示:
結合自己的經驗,由圖可知,日誌,安全,事務等一類的模組在一個軟體項目中的位置,AOP要解決的就是此類問題。 AOP的目標便是對這些“橫切關注點”和業務模組解耦,從而提升軟體的穩定性,擴充性。
AOP通常包含以下主要概念:
- 方面(Aspect):一個關注點的模組化,這個關注點實現可能另外橫切多個對象。交易管理是J2EE應用中橫切關注點中一個很好的例子。
- 連接點(Joinpoint):程式執行過程中明確的點,如方法的調 用或特定的異常被拋出。
- 通知(Advice):在特定的連接點AOP架構執行的動作。各種類型的通知包括“around”、“before”和“throws”通知。通知類型將在下面討論。許多AOP架構都是以攔截器做通知模型,維護一個“圍繞”連接點的攔截器鏈。
- 切入點(Pointcut):指定一個通知將被引發的一系列連接點 的集合。AOP架構必須允許開發人員指定切入點:例如,使用Regex。
- 引入(Introduction):添加方法或欄位到通知化類。
- 介面(IsModified),來簡化緩衝。
- 目標對象(Target object):包含連接點的對象。也被用來 引用通知化或代理化對象。
- AOP代理: AOP架構建立的對象,包含通知。
- 織入(Weaving):組裝方面建立通知化對象。這可以在編譯時間完成(例如使用AspectJ編譯器),也可以在運行時完成。Spring和其他一些純Java AOP架構, 使用運行時織入。
AOP通知類型包括:
- Around通知: 包圍一個連接點的通知,如方法調用。這是最強大的通知。Aroud通知在方法調用前後完成自訂的行為。它們負責選擇繼續執行連接點或直接返回它們自己的傳回值或拋出異常來短路執行。
- Before通知: 在一個連接點之前執行的通知,但這個通知 不能阻止流程繼續執行到連接點(除非它拋出一個異常)。
- Throws通知: 在方法拋出異常時執行的通知。
- After returning通知: 在連接點正常完成後執行的通知, 例如,如果一個方法正常返回,沒有拋出異常。
- Around通知是最通用的通知類型。大部分基於攔截器的AOP架構如Nanning和JBoss4隻提供 Around通知。
通常AOP的關注點有以下幾方面:
- 許可權(Authentication)
- 緩衝(Cache)
- 內容傳遞(Context passing)
- 錯誤處理(Error handling)
- 懶載入(Lazy loading)
- 調試(Debug)
- 日誌(Log)
- 跟蹤,最佳化,校準(tracing, profiling and monitoring)
- 效能最佳化(Performance optimization)
- 持久化(Persistence)
- 資源集區(Resource pooling)
- 同步(Synchronization)
- 事務(Transactions)
瞭解了AOP的應用情境,下面以許可權為例,比較一下傳統方法與AOP方法各自的實現,說明AOP技術的應用。
傳統方法:
BusinessA ClassicsPermission() { if (tag == "Pass") { return new BusinessA(); } throw new Exception("你沒有許可權操作BusinessA."); }
這種是常見的OO做法,它帶來以下一些問題:
1、商務邏輯冗餘:許可權校正過程並不是商務邏輯執行的一部分,這個工作是屬於系統的,但是,在這種情況下,我們不得不把系統的許可權校正過程和商務邏輯執行過程摻雜在一起,造成混亂。
2、代碼冗餘:使用這種方法,我們必須所有的商務邏輯代碼中包含許可權驗證代碼,使得同樣校正的代碼充斥在整個軟體中,造成代碼冗餘。
3、緊耦合:使用這種方法,在業務或許可權任何一方發生改變時都有可能影響到其他部分,造成耦合。下面所有的問題都是因此而來。
4、不易擴充:依次類推,如果要添加其他橫向模組,將導致代碼冗餘,耦合泛濫,到最後甚至不可收拾;
5、不靈活:使用這種方法,任何一個橫向變化都有可能導致代碼的修改;
然而,我們利用AOP就可以很方便的解決上述問題,如下:
[PermissionValidate] class BusinessA { }
上面是AOP的實現方法,可以看到,業務與許可權幾乎沒有關係,上面出現的冗餘,耦合問題迎刃而解。
通過上面描述可知,AOP方法解決的是橫向問題,那麼它是如何?的呢?答案是代理。代理對於客戶,業務都是透明的,只是在其中加入的控制,而這些控制可以根據需求靈活的改變而不影響客戶與業務。代理的基本原理如:
由圖可知,AOP關注的是aProxy,它將橫向業務及變化放在客戶與業務的中間,而不影響二者。
綜上所述,AOP是一種解決軟體中橫向問題(公用模組)的思想,為軟體架構師解決此類問題提供了一種行之有效方法。
註:文中部分內容為本人學習時收集整理而來。