Spring AOP是什麼?

本文內容如有錯誤、不足之處,歡迎技術愛好者們一同探討,在本文下面討論區留言,感謝。

前言

大多數企業應用程序都具有一些常見的橫切關注點,這些關注點適用於不同類型的對象和模塊。一些常見的橫切關注點是日誌記錄,事務管理,數據驗證等。

在面向對象編程中,應用程序的模塊化是通過類實現的,而在面向切面編程中,應用程序的模塊化是通過 Aspects 實現的,它們被配置可以橫向切面不同的類。

Spring AOP從無法通過常規的面向對象的編程模型實現的類中獲取橫切任務的直接依賴關係。例如,有一個單獨的日誌記錄類,但是功能類也必須調用這些方法來實現整個應用程序的日誌記錄。

概述

AOP是一種編程範例,旨在通過允許跨領域關注點的分離來提高模塊化。它是通過在現有代碼中添加其他行爲而無需修改代碼本身來實現的。相反,可以分別聲明此新代碼和這些新行爲。Spring的AOP框架可幫助開發人員實現這些跨領域的關注。

AOP的核心概念

  1. 切面Aspect): 切面由切點和增強(advice)組成。例如事務管理。Aspects 可以是通過 Spring XML 配置配置的普通類,也可以使用 Spring AspectJ 集成通過 @Aspect 註釋將類定義爲 Aspect
  2. 連接點Join Point): 能夠被攔截的地方,因爲 Spring AOP 是基於動態代理的,所以是方法攔截的。例如方法執行,異常處理,更改對象變量值等。在 Spring AOP 中,連接點始終是方法的執行。
  3. 增強Advice): Advices 是針對特定連接點採取的操作。就編程而言,它們是在應用程序中達到具有匹配切入點的特定連接點時執行的方法。可以將 Advices 視爲 Struts2 攔截器或 Servlet 過濾器。
  4. 切點Pointcut): 切點是與連接點匹配的表達式,用於確定是否需要增強。Pointcut 使用與連接點匹配的不同類型的表達式,Spring 框架使用 AspectJ Pointcut 表達式語言。
  5. 目標對象Target Object): 它們是應用增強的對象。Spring AOP 是使用動態代理實現的,因此此對象始終是代理對象。這意味着將在運行時創建一個子類,在該子類中將攔截目標方法,並根據其配置包含增強。
  6. AOP代理AOP proxy):Spring AOP 實現使用JDK動態代理來創建包含目標類和增強調用的Proxy類,這些類稱之爲AOP代理類。我們還可以通過將CGLIB代理添加爲 Spring AOP 項目中的依賴項來使用它。
  7. 織入Weaving): 將增強添加到目標類的具體連接點上的過程。這是通過切面與其他對象鏈接用來創建增強的代理對象的過程。這可以在編譯時,加載時或運行時完成。Spring AOP 在運行時執行編織。

通知 Advice

  • AOP 中的一個重要術語是通知。它是切面在特定的連接點處採取的操作。
  • 連接點是程序的執行點,例如方法的執行或異常的處理。在 Spring AOP 中,連接點始終代表方法的執行。
  • 切入點是匹配聯接點的謂詞或表達式。
  • 通知與切入點表達式關聯,並在與該切入點匹配的任何連接點處運行。
  • Spring 默認使用 AspectJ 切入點表達語言。

具體如下圖所示:圖片地址:https://howtodoinjava.com/spring-aop-tutorial/

在這裏插入圖片描述

AOP advices的幾種類型

  • 前置增強Before advice): Advice 執行在連接點之前,但是它不能阻止執行流程前進到連接點(除非它引發異常)。
  • 後置增強After returning advice): 連接點正常完成後要執行的通知。
  • 拋出增強After throwing advice): 如果方法因拋出異常而退出,則執行增強。
  • Final增強After advice): 無論連接點退出的方式如何(正常或異常返回),均執行增強。
  • 環繞增強Around advice): 環繞連接點的增強,例如方法調用。這是最有力的增強。環繞增強可以在方法調用之前和之後執行自定義行爲。它還負責選擇是返回連接點還是通過返回自己的返回值或引發異常來捷徑增強的方法執行。

例子

Maven依賴

編寫代碼前,需要將 Spring AOP 依賴項導入到項目中:

pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.11</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.11</version>
</dependency>
切面和切入點表達式

編寫帶有 @Aspect 註釋的切面類,並編寫切入點表達式以匹配連接點方法。

@Aspect
public class EmployeeCRUDAspect {
     
    @Before("execution(* EmployeeManager.getEmployeeById(..))")			//連接點 表達式
    public void logBeforeV1(JoinPoint joinPoint)
    {
        System.out.println("EmployeeCRUDAspect.logBeforeV1() : " + joinPoint.getSignature().getName());
    }
}
方法(joint points)

編寫要在其上執行建議並與切入點表達式匹配的方法。

EmployeeManager.java

@Component
public class EmployeeManager
{
    public EmployeeDTO getEmployeeById(Integer employeeId) {
        System.out.println("Method getEmployeeById() called");
        return new EmployeeDTO();
    }
}

在上面的示例中,*logBeforeV1()*將在 *getEmployeeById()*方法之前執行,因爲它與連接點表達式匹配。

運行應用

運行應用同時查看控制檯輸出:

TestAOP.java

public class TestAOP
{
    @SuppressWarnings("resource")
    public static void main(String[] args) {
  
        ApplicationContext context = new ClassPathXmlApplicationContext
                            ("com/howtodoinjava/demo/aop/applicationContext.xml");
 
        EmployeeManager manager = context.getBean(EmployeeManager.class);
  
        manager.getEmployeeById(1);
    }
}

控制檯:

EmployeeCRUDAspect.logBeforeV1() : getEmployeeById
Method getEmployeeById() called
Spring aop tutorial for beginners with example.

參考資料

Spring AOP Tutorial Example(Spring AOP教程示例)

Chapter 6. Aspect Oriented Programming with Spring(第6章使用Spring進行面向切面的編程)

Introduction to Spring AOP(Spring AOP簡介

Spring AOP Overview(Spring AOP概述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章