Spring AOP
- OOP:Object-Oriented Programming,物件導向程式設計;AOP:Aspect-Oriented Programming,面向切面程式設計
- Advisor:spring 自己的 AOP 元件;AspectJ :三方實現的 AOP 元件
- 原理是對目標 bean 建立代理物件,達到增強目的
- 如果目標 bean 實現了介面,就用 JDK 動態代理;如果沒有,就用 CGLIB
- 如果有代理多次(多個切面類)可以透過 @Order 指定切面順序,數值越小,越先生成代理類
- 兩種連線點,分別是 JoinPoint 和 ProceedingJoinPoint,適用於不同的通知
- 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) |
在連線點執行之前和之後都可以執行的通知,允許控制連線點的執行,能夠選擇不執行連線點的方法(這是一個四合一通知)。 |