AOP 概念

讓我們先定義一些核心 AOP 概念和術語。這些術語並非 Spring 專屬。遺憾的是,AOP 術語並不是特別直觀。然而,如果 Spring 使用自己的術語,情況會更加混亂。

  • 切面 (Aspect):關注點的模組化,橫跨多個類別。交易管理是企業 Java 應用程式中橫切關注點的一個很好的例子。在 Spring AOP 中,切面透過使用常規類別(基於 Schema 的方法)或使用 @Aspect 註解註解的常規類別(@AspectJ 風格)來實作。

  • 連接點 (Join point):程式執行期間的某個點,例如方法的執行或例外處理。在 Spring AOP 中,連接點始終表示方法執行。

  • 通知 (Advice):切面在特定連接點採取的動作。不同類型的通知包括 "around"、"before" 和 "after" 通知。(通知類型稍後討論。)許多 AOP 框架,包括 Spring,將通知建模為攔截器,並在連接點周圍維護攔截器鏈。

  • 切入點 (Pointcut):匹配連接點的述詞。通知與切入點運算式相關聯,並在切入點匹配的任何連接點執行(例如,執行具有特定名稱的方法)。切入點運算式匹配的連接點概念是 AOP 的核心,Spring 預設使用 AspectJ 切入點運算式語言。

  • 引介 (Introduction):代表類型宣告額外的方法或欄位。Spring AOP 允許您將新的介面(以及相應的實作)引入到任何 advised 物件。例如,您可以使用引介來使 Bean 實作 IsModified 介面,以簡化快取。(在 AspectJ 社群中,引介稱為 inter-type declaration。)

  • 目標物件 (Target object):正在被一個或多個切面 advised 的物件。也稱為 "advised 物件"。由於 Spring AOP 是透過使用執行時期 Proxy 實作的,因此此物件始終是 Proxy 物件。

  • AOP 代理 (AOP proxy):由 AOP 框架建立的物件,用於實作切面契約(通知方法執行等等)。在 Spring Framework 中,AOP 代理是 JDK 動態 Proxy 或 CGLIB Proxy。

  • 織入 (Weaving):將切面與其他應用程式類型或物件連結以建立 advised 物件。這可以在編譯時(例如,使用 AspectJ 編譯器)、載入時或執行時期完成。與其他純 Java AOP 框架一樣,Spring AOP 在執行時期執行織入。

Spring AOP 包括以下類型的通知

  • 前置通知 (Before advice):在連接點之前運行的通知,但不具有阻止執行流程進行到連接點的能力(除非它拋出例外)。

  • 後置返回通知 (After returning advice):在連接點正常完成後(例如,如果方法在沒有拋出例外的情況下返回)運行的通知。

  • 後置拋出通知 (After throwing advice):如果方法透過拋出例外退出,則運行的通知。

  • 後置 (finally) 通知 (After (finally) advice):無論連接點退出的方式如何(正常或例外返回),都運行的通知。

  • 環繞通知 (Around advice):圍繞連接點(例如方法調用)的通知。這是最強大的通知類型。環繞通知可以在方法調用之前和之後執行自訂行為。它還負責選擇是否繼續進行到連接點,或透過傳回自己的傳回值或拋出例外來捷徑 advised 方法執行。

環繞通知是最通用的通知類型。由於 Spring AOP 與 AspectJ 一樣,提供了全方位的通知類型,我們建議您使用可以實作所需行為的最弱通知類型。例如,如果您只需要使用方法的傳回值更新快取,那麼最好實作後置返回通知,而不是環繞通知,儘管環繞通知可以完成相同的操作。使用最特定的通知類型提供了更簡單的程式設計模型,減少了出錯的可能性。例如,您不需要在用於環繞通知的 JoinPoint 上調用 proceed() 方法,因此,您不會忘記調用它。

所有通知參數都是靜態類型化的,因此您可以處理適當類型的通知參數(例如,方法執行的傳回值類型),而不是 Object 陣列。

切入點匹配的連接點概念是 AOP 的關鍵,這使其與僅提供攔截的舊技術區分開來。切入點使通知能夠獨立於物件導向階層進行目標設定。例如,您可以將提供宣告式交易管理的環繞通知應用於一組跨越多個物件的方法(例如服務層中的所有業務操作)。