如果要做爲一名合格的軟件架構師,AOP是必須知道的一門技術。那麼AOP是什麼呢,這就是今天所討論的內容(也是本人最近一陣子的學習總結,希望大家多多指點)。
AOP,全稱Aspect Oriented Programming,中文名稱叫面向方面編程,也叫面向切面編程。
在實際項目開發過程中,我們往往會注意到有一些模塊/功能,如權限,緩存等,需要存在於軟件的各個業務模塊中,而這些模塊/功能又與業務模塊沒有任何關係,甚至在設計業務模塊時我們完全不用考慮這些模塊/功能的存在,但是在開發過程中才發現這些模塊/功能會給我們帶來無盡的煩惱。因爲傳統的OOP方法考慮問題的出發點往往是要解決問題的本身和延伸,所以遇到此類情況時傳統的OOP方法就很難解決。然而對業務模塊和此類模塊稍作分析,我們就會發現,其實它們本質是相同的,只是解決的問題不同,對一個軟件的關注點不同,如下圖所示:
結合自己的經驗,由圖可知,日誌,安全,事務等一類的模塊在一個軟件項目中的位置,AOP要解決的就是此類問題。 AOP的目標便是對這些“橫切關注點”和業務模塊解耦,從而提升軟件的穩定性,擴展性。
AOP通常包含以下主要概念:
- 方面(Aspect):一個關注點的模塊化,這個關注點實現可能另外橫切多個對象。事務管理是J2EE應用中橫切關注點中一個很好的例子。
- 連接點(Joinpoint):程序執行過程中明確的點,如方法的調 用或特定的異常被拋出。
- 通知(Advice):在特定的連接點AOP框架執行的動作。各種類型的通知包括“around”、“before”和“throws”通知。通知類型將在下面討論。許多AOP框架都是以攔截器做通知模型,維護一個“圍繞”連接點的攔截器鏈。
- 切入點(Pointcut):指定一個通知將被引發的一系列連接點 的集合。AOP框架必須允許開發者指定切入點:例如,使用正則表達式。
- 引入(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技術的應用。
傳統方法:
1
2
3
4
5
6
|
BusinessA
ClassicsPermission() { if (tag
== "Pass" )
{ return new BusinessA(); } throw new Exception( "你沒有權限操作BusinessA." ); } |
這種是常見的OO做法,它帶來以下一些問題:
1、業務邏輯冗餘:權限校驗過程並不是業務邏輯執行的一部分,這個工作是屬於系統的,但是,在這種情況下,我們不得不把系統的權限校驗過程和業務邏輯執行過程摻雜在一起,造成混亂。
2、代碼冗餘:使用這種方法,我們必須所有的業務邏輯代碼中包含權限驗證代碼,使得同樣校驗的代碼充斥在整個軟件中,造成代碼冗餘。
3、緊耦合:使用這種方法,在業務或權限任何一方發生改變時都有可能影響到其他部分,造成耦合。下面所有的問題都是因此而來。
4、不易擴展:依次類推,如果要添加其他橫向模塊,將導致代碼冗餘,耦合氾濫,到最後甚至不可收拾;
5、不靈活:使用這種方法,任何一個橫向變化都有可能導致代碼的修改;
然而,我們利用AOP就可以很方便的解決上述問題,如下:
1
2
|
[PermissionValidate] class BusinessA
{ } |
上面是AOP的實現方法,可以看到,業務與權限幾乎沒有關係,上面出現的冗餘,耦合問題迎刃而解。
通過上面描述可知,AOP方法解決的是橫向問題,那麼它是如何實現的呢?答案是代理。代理對於客戶,業務都是透明的,只是在其中加入的控制,而這些控制可以根據需求靈活的改變而不影響客戶與業務。代理的基本原理如下圖:
由圖可知,AOP關注的是aProxy,它將橫向業務及變化放在客戶與業務的中間,而不影響二者。
綜上所述,AOP是一種解決軟件中橫向問題(公共模塊)的思想,爲軟件架構師解決此類問題提供了一種行之有效的方法。