Spring AOP
AOP這詞聽起來耳熟,然而能清晰把它說清楚應該是少數。學習它,從歷史的程序中看看AOP是何時為何出現,這樣認識會比較立體。
名稱 | 含義 | 應用 |
---|---|---|
POP | Process oriented programming | C |
OOP | Object oriented programming) | Java |
COP | Component oriented programming | ReactiveJS |
AOP | Aspect oriented programming | AspectJ,Spring |
SOP | service oriented programming | Microservices |
從C開始,大家是面向過程程式設計,高階語言Java出現,提出OOP的程式設計法則,OOP在複用的不足催生了AOP。與此同時JS風靡,ReactiveJS提倡的面向元件封裝COP思想被廣泛接受。後端業務的高度複雜化帶來的解耦和自治訴求也使SOP越來越流行。
所以和OOP一樣,AOP也是一種程式設計正規化,通過新增切面點,在不改動已有核心邏輯程式碼的前提下,新增功能或更改程式碼流程。
提出
Xerox PARC的 Gregor Kiczales及其同事提出了AOP概念和相關術語,並以此開發了AspectJ 和AspectWerkz。企業級應用Jboss 4.0 就是完全採用 AOP 的思想來設計的 EJB 容器,它通過了 J2EE 的認證,在工業化應用中被證明表現優秀。Spring 2.0後使用了與AspectJ一樣的註解,但沒有使用 AspectJ 的編譯器,底層是Java庫標準的動態代理技術的實現,所以不需要額外依賴一個 AspectJ 的編譯器。
術語
- Cross-cutting concerns:跨領域的問題
儘管OO模型中的大多數類都執行單個特定功能,但它們通常與其他類共享共同的次要要求。例如,我們可能希望線上程進入或退出方法時向資料訪問層中的類新增日誌記錄,也可以向UI層中的類新增日誌記錄。還有些可能與安全性有關,例如訪問控制或資訊流控制。儘管每個類具有非常不同的主要功能,但執行輔助功能所需的程式碼通常是相同的。
- Advice:通知建議
這是你要應用於現有模型的附加程式碼。比如線上程進入或退出方法時應用的日誌記錄程式碼。
- Pointcut:切入點
這是應用程式中執行點的術語,需要應用交叉關注點。比如,當執行緒進入方法時達到切入點,並且當執行緒退出方法時達到另一個切入點。
- Aspect:切面
切入點和建議的組合被稱為方面。我們通過定義切入點並提供正確的建議,為應用程式新增日誌記錄方面。
AOP用來做什麼?
如上面所提到的,我們可以將日誌記錄,效能統計,安全控制,事務處理,異常處理等程式碼從業務邏輯程式碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非業務邏輯的方法中,進而在這些行為改變的時候不影響業務邏輯的程式碼。
從場景來說Android,iOS,Java Spring都用AOP的專業應用場景。它不是必須,但這些場景用AOP給系統帶來的好處是顯然易見的。我們學習AOP在Java Spring裡的應用,喝水不忘挖井人,那我們先了解下AspectJ。
AspectJ
AspectJ的動機是發現那些使用OOP無法很好處理的問題。比如安全性是貫穿於系統所有模組間的問題,每個模組都需要應用安全機制才能保證整個系統的安全性,這裡的安全策略的實施其實就是一個橫切關注點,使用傳統的程式設計解決此問題非常麻煩而且容易產生差錯,這就正是AOP發揮作用的時候了。
傳統的面向物件程式設計中,每個單元就是一個類,而類似於安全性這方面的問題,它們通常不能集中在一個類中處理因為它們橫跨多個類,這就導致了程式碼無法複用,從而產生了大量程式碼冗餘。
面向切面程式設計的出現正好能處理這種場景,AspectJ應運而生,並定義了AOP,它向Java中加入了連線點(Join Point)和少許新結構:切點(pointcut)、通知(Advice)、型別間宣告(Inter-type declaration)和切面(Aspect)。切點和通知動態地影響程式流程,型別間宣告則是靜態的影響程式的類等級結構,而切面則是對所有這些新結構的封裝。
Spring AOP
Spring AOP 與AspectJ 的初衷一致,都是為了統一處理橫切業務,但與AspectJ不同的是,Spring AOP 並不提供完整的AOP功能(即使它完全可以實現),Spring AOP 更注重的是與Spring IOC容器的結合,並結合該優勢來解決橫切業務的問題。
同時,Spring注意到AspectJ在AOP的實現方式上依賴於特殊編譯器(ajc編譯器),處於應用成本考慮,Spring選擇規避這點,採用動態代理技術的實現原理來構建Spring AOP的內部機制(動態織入),這與AspectJ(靜態織入)有根本的區別。在AspectJ 1.5後提出@Aspect形式的註解風格。Spring也非常快地跟進了這種方式,所以Spring 2.0後便使用了與AspectJ一樣的註解,降低開發人員的理解成本。