Introduction to Spring AOP – Spring AOP简介

最后修改: 2017年 11月 5日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

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

在本教程中,我们将介绍Spring的AOP(面向方面的编程),并学习如何在实际场景中使用这一强大的工具。

It’s also possible to leverage AspectJ’s annotations when developing with Spring AOP, but in this article, we’ll focus on the core Spring AOP XML-based configuration.

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

2. Overview

2.概述

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

AOP是一种编程范式,旨在通过允许跨领域关注点的分离来提高模块化程度。它通过在不修改代码本身的情况下向现有代码添加额外的行为来实现这一目标。

Instead, we can declare the new code and the new behaviors separately.

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

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

Spring的AOP框架有助于我们实现这些跨领域的关注。

3. Maven Dependencies

3.Maven的依赖性

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

让我们先在pom.xml中添加Spring的AOP库依赖。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</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.

依赖关系的最新版本可以检查here.

4. AOP Concepts and Terminology

4.AOP的概念和术语

Let’s briefly go over the concepts and terminology specific to AOP:

让我们简单地回顾一下AOP的具体概念和术语。

Program Execution

4.1. Business Object

4.1.业务对象

A business object is a normal class that has a normal business logic. Let’s look at a 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;
    }
}

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

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

4.2. Aspect

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:

让我们看看我们如何定义一个简单的Aspect。

public class AdderAfterReturnAspect {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    public void afterReturn(Object returnValue) throws Throwable {
        logger.info("value return was {}",  returnValue);
    }
}

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

在上面的例子中,我们定义了一个简单的Java类,它有一个名为afterReturn的方法,该方法接收一个Object类型的参数并记录该值。请注意,即使我们的AdderAfterReturnAspect也是一个标准的类,没有任何Spring注释。

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

在接下来的章节中,我们将看到如何将这个Aspect连接到我们的业务对象。

4.3. Joinpoint

4.3.连接点

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

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

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

在Spring AOP中,一个JoinPoint总是代表一个方法的执行。

4.4. Pointcut

4.4.捷径

A Pointcut is a predicate that helps match an Advice to be applied by an Aspect at a particular JoinPoint.

Pointcut是一个谓词,它有助于匹配Advice,以便由Aspect在特定的JoinPoint应用。

We often associate the Advice with a Pointcut expression, and it runs at any Joinpoint matched by the Pointcut.

我们通常将建议Pointcut表达式联系起来,它在Pointcut匹配的任何Joinpoint上运行。

4.5. Advice

4.5 建议

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

一个建议是一个方面在一个特定的连接点采取的行动。不同类型的建议包括“周围”、”之前”“之后”

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

在Spring中,Advice被建模为一个拦截器,围绕Joinpoint维持一个拦截器链。

4.6. Wiring Business Object and Aspect

4.6.连接业务对象和方面

Now let’s look at how we can wire a Business Object to an Aspect with an After-Returning advice.

现在让我们来看看我们如何用After-Returning建议将一个业务对象连接到一个Aspect。

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

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

<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>

As we can see, we defined a simple bean called simpleAdder, which represents an instance of a Business Object. In addition, we created an instance of an Aspect called AdderAfterReturnAspect.

正如我们所看到的,我们定义了一个名为simpleAdder的简单bean,它代表了一个业务对象的实例。此外,我们创建了一个名为AdderAfterReturnAspect的Aspect的实例。

Of course, XML isn’t our only option here; as mentioned before, AspectJ annotations are fully supported as well.

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

4.7. Configuration at Glance

4.7.配置一览

We can use tag aop:config for defining AOP-related configuration. Within the config tag, we define the class that represents an aspect. Then we give it a reference of “doAfterReturningAspect,” an aspect bean that we created.

我们可以使用标签aop:config来定义AOP相关配置。config标签中,我们定义了代表一个方面的类。然后我们给它一个“doAfterReturningAspect “的引用,一个我们创建的方面Bean。

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

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

Then we define which advice we want to apply. In the above example, we applied the after-returning advice. We defined this in our Aspect AdderAfterReturnAspect by executing the afterReturn method that we defined using the attribute method.

然后我们定义我们要应用的建议。在上面的例子中,我们应用了返回后的建议。我们在我们的Aspect AdderAfterReturnAspect中通过执行我们用属性方法定义的afterReturn方法来定义这个。

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.

Aspect中的这个建议需要一个Object.类型的参数,这个参数让我们有机会在目标方法调用之前和/或之后采取一个行动。在这种情况下,我们只是记录该方法的返回值。

Spring AOP supports multiple types of advice using annotation-based config. This and more examples can be found here and here.

Spring AOP支持使用基于注解的配置的多种类型的建议。这一点以及更多的例子可以在这里这里找到。

5. Conclusion

5.结论

In this article, we illustrated the concepts used in AOP. We also looked at examples of using the AOP module of Spring. If we want to learn more about AOP, we can look at the following resources:

在这篇文章中,我们说明了AOP中使用的概念。我们还看了使用Spring的AOP模块的例子。如果我们想了解更多关于AOP的知识,可以看看以下资源。

The implementation of these examples can be found over on GitHub.

这些示例的实现可以在GitHub上找到over