Spring Boot中面向方面程式設計 (AOP)教程

banq發表於2024-03-20

在編寫複雜的軟體時,處理某些似乎“跨越”程式碼各個部分的任務可能會變得混亂。想想諸如日誌記錄、安全檢查甚至錯誤處理之類的任務。這些就是我們所說的橫切關注點。面向方面程式設計(AOP)突然出現來幫助收拾這個爛攤子。

在本文中,我們將使用簡單的語言和示例來解釋 AOP、它為何有用以及它如何在 Spring Boot 中工作。

什麼是AOP?:
面向方面程式設計(AOP)就像為您的程式碼配備了一個超級英雄。這是一種處理應用程式中隨處出現的煩人的重複任務的方法,而不會使您的主程式碼變得混亂。

為什麼我們需要 AOP?
想象一下你正在建造一座房子。你需要粉刷每個房間,安裝管道,並連線電力。現在,想象一下為每個房間單獨執行這些任務。真是頭疼啊!AOP 就像有一支神奇的畫筆,可以一次粉刷所有房間。它可以節省時間並保持您的房子(程式碼)整潔。

AOP的優點:

  1. 節省時間:AOP 允許您編寫一次並在需要的地方應用它,而不是到處重複相同的程式碼。
  2. 保持整潔:AOP 將混亂的內容(例如日誌記錄或安全檢查)與主程式碼分開,使其更易於理解和更改。
  3. 輕鬆更新:需要調整日誌記錄的工作方式嗎?使用 AOP,您可以在一個地方完成此操作,而無需搜尋整個程式碼庫。
  4. 減少重複:AOP 鼓勵“一次編寫,多次使用”的方法,減少冗餘並使程式碼更加高效。

在 AOP 出現之前什麼是困難的?
在 AOP 出現之前,開發人員必須在他們的應用程式中撒上相同的程式碼,就像在盤子上調味一樣。這使得程式碼難以遵循和更新。AOP 過來說道:“嘿,讓我們把所有這些調味料放在一個地方,這樣我們就可以輕鬆地更換它們。”

AOP中的術語:
1. 方面Aspect:
方面是橫切功能的模組化單元。它封裝了影響多個類或模組的行為,例如日誌記錄、安全性或事務管理。方面定義要做什麼以及何時做,通常使用建議。

2. 建議Advice:
建議Advice 是某個方面在特定連線點採取的操作。它表示到達程式中特定點時需要執行的程式碼,例如方法執行之前、之後或周圍。有不同型別的建議:

  • 之前建議:在連線點之前執行,通常用於日誌記錄或輸入驗證等任務。
  • 返回建議後:在連線點成功完成後執行,對於日誌記錄或資源清理等任務很有用。
  • 丟擲建議後:在連線點丟擲異常後執行,有助於異常處理或記錄錯誤。
  • After(finally)advice:無論連線點的結果(成功或異常)都執行,通常用於清理任務。
  • 圍繞建議:包裝連線點,允許方面控制方法呼叫,包括修改輸入引數或返回值。

3. 連線點Join Point:
連線點是程式執行中的特定點,例如方法呼叫、方法執行或異常處理。方面可以透過選擇適當的連線點來指定應應用它們的位置。

4. 切入點Pointcut:
切入點是匹配程式執行流程中連線點的謂詞。它透過指定應執行建議的條件來定義應應用方面的位置。切入點使用表示式來指定連線點,通常基於方法簽名或執行位置。

5. 編織Weaving:
編織是將方面整合到應用程式程式碼的指定連線點的過程。編織主要有以下三種型別:

  • 編譯時編織:在編譯過程中,方面被編織到應用程式程式碼中。
  • 載入時編織:在類載入到記憶體之前,方面在執行時編織到應用程式程式碼中。
  • 執行時編織:在應用程式執行時,方面動態地編織到應用程式程式碼中。

6. AspectJ:
 AspectJ 是 Java 程式語言的流行擴充套件,提供對 AOP 構造的支援。它提供了強大的切入點表示式語言,並與 Java 應用程式無縫整合,允許開發人員編寫方面並將其應用到他們的程式碼庫中。

實用示例:
Spring Boot 中的日誌方面:假設您有一個 Spring Boot 應用程式,其中有一個執行某些業務邏輯的服務。您希望記錄該服務的方法呼叫,而不需要在程式碼庫中加入日誌語句。

解釋:

定義 Aspect:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Before(<font>"execution(* com.example.demo.service.*.*(..))")
    public void beforeServiceMethods() {
        System.out.println(
"Logging: Service method is being called.");
    }
}


應用Aspect:

import org.springframework.stereotype.Service;

@Service
public class MyService {

    public void doSomething() {
        System.out.println(<font>"Doing something in MyService.");
    }
}

以下是執行 Spring Boot 應用程式時的預期輸出:

Logging: Service method is being called.
Doing something in MyService.

解釋:

  • 第一行是日誌方面在執行 doSomething() 方法之前生成的日誌資訊。
  • 第二行是 MyService 類 doSomething() 方法的輸出。

該輸出演示了日誌方面如何攔截方法呼叫並在實際方法執行前執行日誌邏輯,展示了 Spring Boot 中面向方面程式設計 (AOP) 的強大功能。

相關文章