学习在 Spring Boot 应用程序中实现 AOP,并使用 AspectJ 添加不同的 aop 建议,以支持诸如日志记录,性能分析,缓存和事务管理之类的跨领域关注点。
阅读更多: Spring AOP 教程
1. 使用 Spring Boot 设置 AOP
1.1. Maven
在 Spring Boot 中设置 AOP 需要包括spring-boot-starter-aop
依赖项。 它将spring-aop
和aspectjweaver
依赖项导入到应用程序中。 入门 pom.xml
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
1.2. 启用/禁用自动配置
导入以上依赖项会触发AopAutoConfiguration
,这会使用@EnableAspectJAutoProxy
注解启用 AOP。
如果application.properties
中的spring.aop.auto = false
不激活自动配置。
application.properties
#spring.aop.auto = false //'false' disables the auto configuration
1.3. 使用@Aspect
创建切面
可以在 Spring 运行中使用注解@Aspect
注解创建一个切面,并使用@Component
注解在 bean 容器中注册。
在切面类中,我们可以根据需要创建建议。 例如,下面的类在包com.howtodoinjava.aop
中所有类内的方法上对建议应用。 它捕获方法的开始时间和结束时间,并将总的方法执行时间记录在日志文件中。
LoggingAspect.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
@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
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
2019-11-07T21:02:58.390+0530 INFO Execution time of DomainService.getDomainObjectById :: 1145 ms
如我们所见,AOP 建议已应用于服务方法。
2. 建议类型
在 Aspectj AOP 中有五种类型的建议。
@Before
:在连接点之前执行的建议,但是它不能阻止执行流程前进到连接点(除非它引发异常)。@AfterReturning
:连接点正常完成后要执行的建议。@AfterThrowing
:如果方法因抛出异常而退出,则要执行的建议。@After
:无论连接点退出的方式如何(正常或异常返回),都将执行建议。@Around
:围绕连接点的建议,例如方法调用。
3. 结论
使用 Spring 运行实现 AOP 只需很少的工作,并且一旦添加spring-boot-starter-aop
依赖项,我们就准备添加切面。
每当我们想禁用 aop 自动配置时,我们都可以通过切换到 false
轻松完成。
创建切面和建议就像添加一些注解一样简单,例如@Aspect
,@Around
等。
学习愉快!