AOP 及 Spring AOP 簡述
探討 AOP 概念及 Spring AOP 應用

這篇文章是初學的時候撰寫的,其中一些觀念並不正確,步驟也可能因為更新或觀念問題而不適用或者多餘,此篇文章僅為留做紀錄

  • AOP(Aspect-Oriented Programming) 是一種基於 OOP(Object-Oriented Programming) 的改進
  • AOP 是基於動態代理 (Dynamic Proxy) 這種 design pattern
  • AOP 主要的設計對象是切面 (Aspect),而切面是用來模組化橫切關注點 (Cross-Cutting Concern)
  • 切面需要定義公共功能,但可以明確定義功能在哪裡或以什麼方式應用,而不必修改受影響的類別。如此切面關注點就可以被模組化到特殊的類別 (切面) 裡面

優點

  • 交易相關的邏輯位於同一位置,便於維護與升級
  • 業務邏輯更簡潔,只包含核心業務代碼

術語及概念

  • Cross-Cutting Concern 橫切關注點:橫跨應用系統多個流程、模組的功能,例如日誌 (Logging)、安全 (Security) 檢查、交易 (Transaction) 等動作,在許多流程的多個位置都需要執行,這種動作就被稱為橫切關注點
  • Aspect 切面:橫切關注點被模組化後的一種特殊物件;還未模組化前是橫切關注點,抽取後成為一組一組的切面;另一方面來說代理會將一個一個切面重組為橫切關注點
  • Advice 通知:切面必須要完成的工作或行為,也就是切面的實作內容。切面裡面的各個方法即是一個、一個的通知
  • Target 目標:被通知的物件,也就是要被橫切的業務邏輯類別
  • Proxy 代理:向目標物件通知之後創建的對象。容器會建立一個代理,依照設定去縫合 (weave) 切面到應用程式中
  • JoinPoint 連接點:程序執行的某個特定位置或時機。例如某個類別的某個方法呼叫前、呼叫後、拋出異常後等等。
    • 連接點由兩個因素決定:以方法表示的程式執行點、相對執行點表示的方位。例如 A 類別的 a() 方法執行前的 JoinPoint 連接點決定要素為:執行點 A#a(),方位為執行前的位置
    • 概念類比:JoinPoint 連接點相當於資料庫的紀錄,切面相當於查詢條件
  • Pointcut 切面定義:每個類別都有多個連接點,類別的所有方法某種程度上都可以想成是 JoinPoint 連接點。AOP通過切面定位到特定的連接點

Spring AOP

  • AspectJ:Java 社群最完整、最廣為人知的 AOP 實作
  • Spring 2.0 以上,可以使用基於 AspectJ 的 annotation 註解或基於 XML 設定的 AOP

Dependencies

Spring

  • commons logging
  • spring beans
  • spring context
  • spring core
  • spring expression

Spring AOP

  • aopalliance
  • aspectj weaver
  • spring aop
  • spring aspects

註:Spring 框架的版本可以更動,但須一致

設定

  • 在 XML 文件中加入 aop namespace

基於註解的方式

  • 在 XML 文件中加入以下設定:
    • <aop:aspectj-autoproxy/>
  • 把橫切關注點的程式碼抽象到切面的類別中
    • 切面首先是一個 IOC 中的 bean,所以要加上 @Component 註解
    • 切面還需要加入 @Aspect 註解
  • 在類別中聲明各種通知:
    • 聲明一個方法
    • 在方法前加入五種註解,並配合要通知的目標:
      • @Before:執行點之前
      • @After:執行點之後,但無法取得回傳值
      • @AfterReturning:執行點之後,但可以取得回傳值,執行順序在 @After 之前
      • @AfterThrowing:執行出現異常後,可以取得異常資訊,執行順序在 @After 之前
      • @Around:執行點前、後、回傳值等全都包括,通常會配合 ProceedingJoinPoint 類別當參數使用
  • 可以在通知方法中聲明一個類別為 JoinPoint 的參數,然後就可以藉此物件取出目標連接點的細節,例如方法名稱及其參數等

基於 XML 文件的方式

  • 所有相關類別都不需要任何註解
  • XML 文件中加入 aop 跟 beans namespace
  • 在 XML 文件中先設定好有關的 bean,包括目標類別及切面類別
  • 再於 XML 文件中在<aop:config></aop:config>元素內設定 AOP 有關設定
  • 其中設定的元素跟屬性都跟註解相同

Last modified on 2018-04-10