1. 引言
在本教程中,我們將介紹使用 Spring 實現面向切切面編程 (AOP),並學習如何在實際場景中使用這個強大的工具。
此外,在與 Spring AOP 結合使用時,還可以利用 AspectJ 的註解,但本文將重點介紹基於 XML 的 Spring AOP 配置。
2. 概述
AOP 是一種編程範式,旨在通過允許分離橫切關注點來提高模塊化程度。
它通過在不修改原始代碼的情況下向現有代碼添加額外的行為來實現這一點。
相反,我們可以獨立聲明新的代碼和新的行為。
Spring 的 AOP 框架 幫助我們實施這些橫切關注點。
3. Maven 依賴
讓我們首先在 pom.xml 中添加 Spring 的 AOP 庫依賴:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>最新版本的依賴項可以在這裏進行檢查:這裏。
4. AOP 概念與術語
我們簡要回顧一下 AOP 相關的概念和術語:
4.1. 業務對象
業務對象是一個具有正常業務邏輯的普通類。下面我們來看一個簡單的業務對象示例,它只是將兩個數字相加:
public class SampleAdder {
public int add(int a, int b) {
return a + b;
}
}
請注意,該類是一個普通的業務邏輯類,不包含任何與Spring相關的註解。
4.2. 方面 (Aspect)
方面是一種模塊化,它跨越多個類來處理一個關注點。統一日誌記錄就是一個典型的跨關注點例子。
讓我們來看如何定義一個簡單的方面:
public class AdderAfterReturnAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void afterReturn(Object returnValue) throws Throwable {
logger.info("value return was {}", returnValue);
}
}
在上述示例中,我們定義了一個簡單的 Java 類,該類有一個名為 afterReturn 的方法,該方法接受一個類型為 Object 的參數並記錄其值。請注意,我們的 AdderAfterReturnAspect 只是一個標準類,沒有 Spring 註解。
在下一部分,我們將看到如何將此方面連接到我們的業務對象。
4.3. 連接點 (Joinpoint)
連接點 (Joinpoint) 是指在程序執行過程中,例如方法執行或異常處理等特定時刻。
在 Spring AOP 中,連接點 (Joinpoint) 始終代表一個方法執行。
4.4. 切入點
切入點 是一個謂詞,用於將 建議 匹配到由 方面 在特定 連接點 上應用的幫助。
我們通常將 建議 與 切入點 表達式關聯起來,並且它會在與 切入點 匹配的任何 連接點 上運行。
4.5. 建議
建議是指在特定連接點上由一個方面執行的動作。 建議的類型包括“環繞”、“前置”和“後置”。
在 Spring 中,建議被建模為攔截器,圍繞連接點維護攔截器鏈。
4.6. 將業務對象和方面連接起來
現在讓我們看看如何使用“After-Returning”建議將業務對象連接到方面。
下面是我們在 <beans> 標籤中的標準 Spring 配置中放置的配置片段:
<bean id="sampleAdder" class="org.baeldung.logger.SampleAdder" />
<bean id="doAfterReturningAspect"
class="org.baeldung.logger.AdderAfterReturnAspect" />
<aop:config>
<aop:aspect id="aspects" ref="doAfterReturningAspect">
<aop:pointcut id="pointCutAfterReturning" expression=
"execution(* org.baeldung.logger.SampleAdder+.*(..))"/>
<aop:after-returning method="afterReturn"
returning="returnValue" pointcut-ref="pointCutAfterReturning"/>
</aop:aspect>
</aop:config>
如我們所見,我們定義了一個簡單的 Bean,名為 simpleAdder,它代表了一個 Business Object 的實例。此外,我們還創建了一個 Aspect 的實例,名為 AdderAfterReturnAspect。
當然,XML 並不是我們的唯一選擇;正如之前提到的,AspectJ 註解也得到完全支持。
4.7. 快速配置概覽
我們可以使用 <em>aop:config</em> 標籤來定義與 AOP 相關的配置。 <em>aop:config</em> 標籤內,我們定義代表切面的類。 然後我們為其提供一個對 <em>“doAfterReturningAspect”</em> 的引用,這是一個我們創建的切面 Bean。
接下來,我們使用 <em>pointcut</em> 標籤定義一個 Pointcut。 上面的示例中使用的 Pointcut 是 <em>execution(* org.baeldung.logger.SampleAdder+.*(..))</em>,這意味着該 Pointcut 會在 SampleAdder 類中的任何方法上應用建議,無論該方法接受多少個參數,以及無論其返回值類型如何。
然後,我們定義要應用的建議類型。 在上面的示例中,我們應用了 after-returning 建議。 我們通過執行使用屬性方法定義的 <em>afterReturn</em> 方法,在我們的 Aspect <em>AdderAfterReturnAspect</em> 中定義了它。
這個 Aspect 中的建議參數類型為 <em>Object</em>。 該參數為我們提供了一個在目標方法調用之前和/或之後執行操作的機會。 在這種情況下,我們只是記錄目標方法的返回值。
Spring AOP 支持多種類型的建議,使用基於註解的配置。 更多示例可以在這裏和這裏找到。
5. 結論
本文介紹了 AOP 中使用的概念,並探討了 Spring AOP 模塊的用法。如果您想進一步學習 AOP,可以參考以下資源:
- AspectJ 簡介
- 實現自定義 Spring AOP 註解
- Spring 中的切面點表達式簡介
- Spring AOP 與 AspectJ 比較
- Spring 中的 Advice 類型簡介