Spring AOP 简介

时间:2023-01-13 11:12:59

Spring AOP 简介

翻译原文链接 Introduction to Spring AOP

1. 简介

在本教程中,我们将通过 Spring 介绍 AOP(面向切面​​的编程),并开始了解如何在实际场景中开始使用这个强大的工具。

In this tutorial, we’ll introduce AOP (Aspect Oriented Programming) with Spring and start understanding how we can start using this powerful tool in practical scenarios.

在使用 Spring AOP 进行开发时,也可以利用 AspectJ 的注解,但在本文中,我们关注核心 Spring AOP 基于 XML 的配置。

It's also possible to leverage AspectJ's annotations when developing using Spring AOP but in this article, we're focusing on the core Spring AOP XML-based configuration.

2. 概述

AOP 是一种编程范式,旨在通过允许分离横切关注点来增加模块化。它通过向现有代码添加额外行为而不修改代码本身来实现。

AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code without modification of the code itself.

相反,我们可以分别声明这个新代码和这些新行为。

Instead, we can declare this new code and these new behaviors separately.

Spring 的 AOP 框架帮助我们实现这些横切关注点。

Spring's AOP framework helps us implement these cross-cutting concerns.

3. Maven 依赖项

我们首先在 pom.xml 中添加 SpringAOP 库依赖:

Let's start by adding Spring's AOP library dependency in the pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.0</version>
</parent>
 
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>

可以在此处检查依赖项的最新版本

The latest version of the dependency can be checked here.

4. AOP 概念和术语

让我们简要回顾一下 AOP 特有的概念和术语:

Let's briefly go over the concepts and terminology specific to AOP: Spring AOP 简介

4.1. 业务对象

业务对象是具有正常业务逻辑的普通类。让我们看一个简单的业务对象示例,其中我们只将两个数字相加:

A business object is a normal class which has a normal business logic. Let's look at simple example of a business object where we just add two numbers:

public class SampleAdder {
    public int add(int a, int b) {
        return a + b;
    }
}

注意这个类是一个普通的类,有业务逻辑,没有任何Spring相关的注解。

Note that this class is a normal class with business logic and without any Spring-related annotations.

4.2. 切面

切面是跨越多个类的关注点的模块化(类)。统一日志记录就可以是这种横切关注点的一个例子。

An aspect is a modularization of a concern that cuts across multiple classes. Unified logging can be an example of such cross-cutting concern.

让我们看看如何定义一个简单的切面:

Let's see how we define a simple 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 注解。

In the above example, we've just defined a simple Java class which has a method called afterReturn that takes one argument of type Object and it just logs in that value. Note that even our AdderAfterReturnAspect is a standard class, free of any Spring annotations.

在接下来的部分中,我们将看到如何将此切面连接到我们的业务对象。

In the next sections, we'll see how we can wire this Aspect to our Business Object.

4.3. 连接点

连接点是程序执行过程中的一个点,例如方法的执行或异常的处理。

A Joinpoint is a point during the execution of a program, such as execution of a method or the handling of an exception.

在 Spring AOP 中,一个连接点 始终代表一个方法执行。

In Spring AOP, a JoinPoint always represents a method execution.

4.4. 切点

切点是一个谓词,它有助于匹配一个由特定连接点处的切面应用的通知。 A Pointcut is a predicate that helps match an Advice to be applied by an Aspect at a particular JoinPoint.

通知 通常与一个切点表达式相关联,并在与切点匹配的任何连接点上运行。

The Advice is often associated with a Pointcut expression and runs at any Joinpoint matched by the Pointcut.

4.5. 通知

通知 是切面在特定连接点处采取的行动。不同类型的通知包括环绕前置后置 通知。

An advice is an action taken by an aspect at a particular Joinpoint. Different types of advice include “around,” “before” and “after” advice.

Spring 中,一个 通知 被建模为一个拦截器,在连接点周围维护一个拦截器链。

In Spring, an Advice is modeled as an interceptor, maintaining a chain of interceptors around the Joinpoint.

4.6. 连接业务对象和切面

让我们看看如何使用返回后通知将业务对象连接到切面。

Let's look at how we can wire a Business object to an Aspect with an After-Returning advice.

下面是我们将在 <beans> 标签中放置在标准 Spring 配置中的配置摘录:

Below is the config excerpt that we'd place in a standard Spring config in the “<beans>” tag:

<bean  class="org.baeldung.logger.SampleAdder" />
<bean  
  class="org.baeldung.logger.AdderAfterReturnAspect" />
<aop:config>
    <aop:aspect  ref="doAfterReturningAspect">
       <aop:pointcut  expression=
         "execution(* org.baeldung.logger.SampleAdder+.*(..))"/>
       <aop:after-returning method="afterReturn"
         returning="returnValue" pointcut-ref="pointCutAfterReturning"/>
    </aop:aspect>
</aop:config>

可以看出,我们定义了一个名为 simpleAdder 的简单 bean,它表示业务对象的一个​​实例。此外,我们正在创建一个名为 AdderAfterReturnAspectAspect 实例。

As can be seen, we've defined a simple bean called simpleAdder which represents an instance of a Business Object. In addition, we're creating an instance of an Aspect called AdderAfterReturnAspect.

当然,XML 不是我们唯一的选择;如前所述,也完全支持 AspectJ 注释。

XML is, of course, not our only option here; as mentioned before, AspectJ annotations are fully supported as well.

4.7. 配置概览

标签 aop:config 用于定义 AOP 相关的配置。在 config 标签中,我们定义了代表一个切面的类。我们已经给它一个我们创建的 doAfterReturningAspect 切面 bean 的引用。

Tag aop:config is used for defining AOP-related configuration. Within the config tag, we define the class that represents an aspect. We've given it a reference of “doAfterReturningAspect” aspect bean that we created.

接下来,我们使用 aop:pointcut 标签定义一个切点。上例中使用的切点(表达式)是 execution(* org.baeldung.logger.SampleAdder+.*(..)) 这意味着对 SampleAdder 类中的任何方法应用建议,该方法接受任意数量的参数并返回任何值类型。

Next, we define a Pointcut using the pointcut tag. Pointcut used in the example above is execution(* org.baeldung.logger.SampleAdder+.*(..)) which means apply an advice on any method within SampleAdder class that accepts any number of arguments and returns any value type.

然后,我们定义要应用的通知。在上面的示例中,我们将通过执行使用属性方法定义的名为 afterReturn 的方法来应用在我们的切面 AdderAfterReturnAspect 中定义的 返回后通知

Next, we define which advice we want to apply. In the above example, we're going to apply after-returning advice which is defined in our Aspect AdderAfterReturnAspect by executing method named afterReturn defined using attribute method.

切面 中的这个 通知 采用一个 Object 类型的参数。该参数使我们有机会在目标方法调用之前 和/或 之后采取行动。在这个案例里,我们只记录方法的返回值。

This advice within Aspect takes one parameter of type Object. The parameter gives us an opportunity to take an action before and/or after the target method call. In this case, we just log the method’s return value.

Spring AOP 支持使用基于注解的配置的多个通知——可以在 Spring 中的Advice类型介绍Spring 中的切点表达式介绍 找到这个和更多的例子。

Spring AOP supports multiple advices using annotation-based config – this and more examples can be found here and here.

5. 总结

在本教程中,我们阐释了 AOP 中使用的概念以及使用 Spring 的 AOP 模块的示例。如果您有兴趣了解有关 AOP 的更多信息,这里有一些资源:

In this tutorial, we illustrated concepts used in AOP and example of using the AOP module of Spring. If you're interested in discovering more about AOP, here're some resources:

这些示例的实现可以在 GitHub 项目中找到——这是一个基于 Maven 的项目,因此应该很容易导入和按原样运行。

The implementation of these examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as is.