学习在 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@Componentpublic 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 detailsString className = methodSignature.getDeclaringType().getSimpleName();String methodName = methodSignature.getName();final StopWatch stopWatch = new StopWatch();//Measure method execution timestopWatch.start();Object result = proceedingJoinPoint.proceed();stopWatch.stop();//Log method execution timeLOGGER.info("Execution time of " + className + "." + methodName + " "+ ":: " + stopWatch.getTotalTimeMillis() + " ms");return result;}}
1.4. 示例
创建一个简单的服务类来测试以上建议。
DomainService.java
@Servicepublic 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)@SpringBootTestpublic class AopSpringBootTest{@Autowiredprivate DomainService service;@Testpublic 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等。
学习愉快!
