# Spring Boot 和 AOP

> 原文： [https://howtodoinjava.com/spring-boot2/aop-aspectj/](https://howtodoinjava.com/spring-boot2/aop-aspectj/)

学习在 Spring Boot 应用程序中实现 AOP，并使用 [AspectJ](https://www.eclipse.org/aspectj/) 添加不同的 aop 建议，以支持诸如日志记录，性能分析，缓存和事务管理之类的跨领域关注点。

> 阅读更多： [Spring AOP 教程](https://howtodoinjava.com/spring-aop-tutorial/)

## 1\. 使用 Spring Boot 设置 AOP

#### 1.1. Maven

在 Spring Boot 中设置 AOP 需要包括`spring-boot-starter-aop`依赖项。 它将`spring-aop`和`aspectjweaver`依赖项导入到应用程序中。 [入门 pom.xml](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-starters/spring-boot-starter-aop/pom.xml)

`pom.xml`

```java
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

```

#### 1.2. 启用/禁用自动配置

导入以上依赖项会触发[`AopAutoConfiguration`](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.html)，这会使用`@EnableAspectJAutoProxy`注解启用 AOP。

如果`application.properties`中的`spring.aop.auto = false`不激活自动配置。

`application.properties`

```java
#spring.aop.auto = false	//'false' disables the auto configuration

```

#### 1.3. 使用`@Aspect`创建切面

可以在 Spring 运行中使用注解`@Aspect`注解创建一个切面，并使用`@Component`注解在 bean 容器中注册。

在切面类中，我们可以根据需要创建建议。 例如，下面的类在包`com.howtodoinjava.aop`中所有类内的方法上对建议应用。 它捕获方法的开始时间和结束时间，并将总的方法执行时间记录在日志文件中。

`LoggingAspect.java`

```java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class LoggingAspect 
{
	private static final Logger LOGGER = LogManager.getLogger(LoggingAspect.class);

	@Around("execution(* com.howtodoinjava.aop..*(..)))")
    public Object profileAllMethods(ProceedingJoinPoint proceedingJoinPoint) throws Throwable 
    {
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();

        //Get intercepted method details
        String className = methodSignature.getDeclaringType().getSimpleName();
        String methodName = methodSignature.getName();

        final StopWatch stopWatch = new StopWatch();

        //Measure method execution time
        stopWatch.start();
        Object result = proceedingJoinPoint.proceed();
        stopWatch.stop();

        //Log method execution time
        LOGGER.info("Execution time of " + className + "." + methodName + " "
        					+ ":: " + stopWatch.getTotalTimeMillis() + " ms");

        return result;
    }
}

```

#### 1.4. 示例

创建一个简单的服务类来测试以上建议。

`DomainService.java`

```java
@Service
public class DomainService 
{
	public Object getDomainObjectById(Long id)
	{
		try {
			Thread.sleep(new Random().nextInt(2000));
		} catch (InterruptedException e) {
			//do some logging
		}
        return id;
    }
}

```

创建一个测试类并执行给定的方法并注意日志。

`AopSpringBootTest.java`

```java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AopSpringBootTest 
{
	@Autowired
	private DomainService service;

	@Test
	public void testGetDomainObjectById() 
	{
		service.getDomainObjectById(10L);
	}
}

```

`Console`

```java
2019-11-07T21:02:58.390+0530 INFO Execution time of DomainService.getDomainObjectById :: 1145 ms

```

如我们所见，AOP 建议已应用于服务方法。

## 2\. 建议类型

在 Aspectj AOP 中有五种类型的建议。

1.  [`@Before`](https://howtodoinjava.com/spring-aop/aspectj-before-annotation-example/) ：在连接点之前执行的建议，但是它不能阻止执行流程前进到连接点（除非它引发异常）。
2.  [`@AfterReturning`](https://howtodoinjava.com/spring-aop/aspectj-after-returning-annotation-example/) ：连接点正常完成后要执行的建议。
3.  [`@AfterThrowing`](https://howtodoinjava.com/spring-aop/aspectj-afterthrowing-annotation-example/) ：如果方法因抛出异常而退出，则要执行的建议。
4.  [`@After`](https://howtodoinjava.com/spring-aop/aspectj-after-annotation-example/) ：无论连接点退出的方式如何（正常或异常返回），都将执行建议。
5.  [`@Around`](https://howtodoinjava.com/spring-aop/aspectj-around-annotation-example/) ：围绕连接点的建议，例如方法调用。

## 3\. 结论

使用 Spring 运行实现 AOP 只需很少的工作，并且一旦添加`spring-boot-starter-aop`依赖项，我们就准备添加切面。

每当我们想禁用 aop 自动配置时，我们都可以通过切换到 `false`轻松完成。

创建切面和建议就像添加一些注解一样简单，例如`@Aspect`，`@Around`等。

学习愉快！

[`下载源码`](https://github.com/lokeshgupta1981/SpringExamples/tree/master/aop)