AOP

CyrusHuang發表於2024-11-02

Spring AOP

  • OOP:Object-Oriented Programming,物件導向程式設計;AOP:Aspect-Oriented Programming,面向切面程式設計
  • Advisor:spring 自己的 AOP 元件;AspectJ :三方實現的 AOP 元件
  • 原理是對目標 bean 建立代理物件,達到增強目的
    • 如果目標 bean 實現了介面,就用 JDK 動態代理;如果沒有,就用 CGLIB
    • 如果有代理多次(多個切面類)可以透過 @Order 指定切面順序,數值越小,越先生成代理類
  • 兩種連線點,分別是 JoinPointProceedingJoinPoint,適用於不同的通知
    • JoinPoint:獲取連線點資訊,比如方法、引數、目標物件等,可用於 @Before@After@AfterReturning
    • ProceedingJoinPoint:是 JointPoint 的子介面,額外提供 proceed() 來執行目標方法,僅用於 @Around
  • 宣告式事務 @Transactional 註解底層就使用 AOP 實現事務提交回滾的

AspectJ VS Advisor

說人話 AspectJ 更強大、效能更好、可以不依賴 spring;總結就是:簡單場景使用 Advisor,複雜場景使用 AspectJ。下面是兩者詳細對比

AspectJ Advisor
定義 AspectJ 是一個完整的 AOP 框架,支援面向切面程式設計的編譯時和執行時特性。 Advisor 是 Spring AOP 的一個概念,表示一個切面中的通知和切入點的組合。
程式設計模型 提供了豐富的語言支援,包括註解、XML 配置和程式碼注入。 主要透過註解(如 @Before, @After)或 XML 配置來定義。
切面實現 可以在編譯時、類載入時或執行時進行織入,支援複雜的切點表示式。 主要透過 Spring 容器在執行時使用動態代理實現,切點表示式相對簡單。
織入方式 支援編譯時織入、類載入時織入和執行時織入。 僅支援執行時織入,通常使用 Java 動態代理或 CGLIB 代理。
切點表示式 使用 AspectJ 表示式,支援更復雜的匹配規則。 使用 Spring AOP 的切點表示式,功能相對有限。
應用範圍 可用於任何 Java 應用,包括獨立 Java 程式和 Spring 應用。 主要用於 Spring 應用中,與 Spring 生態系統緊密整合。
支援的通知型別 支援多種通知型別,如 @Before, @After, @Around, @AfterReturning, @AfterThrowing 支援 Before, After, Around 和其他通知型別,通常由 Advisor 定義。
效能 AspectJ 的效能較高,因為它可以在編譯時進行最佳化。 Spring AOP 的效能相對較低,因為它依賴於執行時代理。
易用性 對於初學者來說,學習曲線可能較陡峭。 更加簡單直觀,易於上手。

AOP 概念

概念 定義 說人話
切面 (Aspect) 定義了一個橫切關注點的模組,包含通知和切入點。 就是我們定義的切面類
連線點 (Join Point) 程式執行過程中一個可以插入通知的點,例如方法呼叫、方法執行、物件建立等。 目標物件所有方法
切入點 (Pointcut) 定義在哪些連線點上應用通知的規則或表示式,決定通知的應用範圍。 目標物件被增強的方法
通知 (Advice) 在連線點上執行的行為,分為前置通知、後置通知、返回通知、異常通知和環繞通知。
織入 (Weaving) 將切面與目標物件結合的過程,發生在編譯時、類載入時或執行時。 將切點和通知組合的過程
目標物件 (Target Object) 被切面影響的物件,通常是包含業務邏輯的類。

通知

通知型別 描述
前置通知 (Before) 在連線點執行之前執行的通知。
後置通知 (After) 在連線點執行之後執行的通知,通常在連線點成功或失敗後都會執行。
返回通知 (After Returning) 在連線點成功完成後執行的通知,可以訪問連線點的返回值(目標方法執行不能發生異常)。
異常通知 (After Throwing) 在連線點丟擲異常時執行的通知,可以訪問異常資訊。
環繞通知 (Around) 在連線點執行之前和之後都可以執行的通知,允許控制連線點的執行,能夠選擇不執行連線點的方法(這是一個四合一通知)。