Spring Boot中的AOP(Aspect Oriented Programming, 面向切面编程)可以让我们实现一些与业务逻辑无关的功能,如日志、事务、安全等。
把这些跨切面关注点抽取出来,实现解耦。
使用切面承载这些功能的实现,而不污染业务逻辑。
在定义好的切入点Join Point,执行这些功能,比如方法调用前后。
Spring AOP实现了动态代理,无需修改源码即可集成这些切面逻辑。
常用的切面功能有日志记录、性能统计、安全控制、事务管理等。
在Spring Boot中可以通过@Aspect、@Pointcut等注解声明切面。
通过@Before、@After、@Around定义Advice实现切面的功能。
使用方便,只需要添加注解配置,即可在应用中集成AOP。
标注该类是一个切面类
定义一个切入点,可以是一个规则表达式,也可以是一个注解等
前置通知,在目标方法调用前执行
后置通知,在目标方法执行后调用
返回通知,在目标方法正常返回后调用
异常通知,在目标方法抛出异常后调用
环绕通知,围绕目标方法执行
定义切面的优先级,值越小优先级越高
开启Spring对AspectJ切面的支持
JDK17
SpringBoot 3.1.0
4.0.0 org.springframework.boot spring-boot-starter-parent3.1.0 org.example springboot-aspect1.0-SNAPSHOT 17 17 UTF-8 org.springframework.boot spring-boot-starter-aoporg.projectlombok lombokorg.springframework.boot spring-boot-starter-web
@Aspect @Component @Slf4j public class CalcAspect { @Pointcut("execution(* com.example.service.CalcService.*(..))") private void pointcut() { } @Before("pointcut()") public void before() { log.info("********** @Before 前置通知"); } @After("pointcut()") public void after() { log.info("******** @After 后置通知"); } @AfterReturning("pointcut()") public void afterReturning() { log.info("******* @AfterReturning 返回通知"); } @AfterThrowing("pointcut()") public void afterThrowing() { log.info("******** @AfterThrowing 异常通知"); } @Around("pointcut()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object result; log.info("******** 环绕通知之前"); result = proceedingJoinPoint.proceed(); log.info("******** 环绕通知之后"); return result; } }
/** * 计算服务实现 * 微信公众号:架构殿堂 */ @Service @Slf4j public class CalcServiceImpl implements CalcService { @Override public int add(int a, int b) { log.info("=========== CalcService 调用开始"); int result = a + b; log.info("=========== CalcService 调用结束"); return result; } }
@RequiredArgsConstructor @RestController @RequestMapping("/calc") public class CalculatorController { private final CalcService calcService; @GetMapping("/add") public int add(@RequestParam("a") int a, @RequestParam("b") int b) { return calcService.add(a, b); } }
2T22:37:34.639+08:00 INFO 10480 --- [nio-8080-exec-1] com.example.aspect.CalcAspect : ******** 环绕通知之前 2023-09-02T22:37:34.640+08:00 INFO 10480 --- [nio-8080-exec-1] com.example.aspect.CalcAspect : ********** @Before 前置通知 2023-09-02T22:37:34.641+08:00 INFO 10480 --- [nio-8080-exec-1] c.example.service.impl.CalcServiceImpl : =========== CalcService 调用开始 2023-09-02T22:37:34.641+08:00 INFO 10480 --- [nio-8080-exec-1] c.example.service.impl.CalcServiceImpl : =========== CalcService 调用结束 2023-09-02T22:37:34.642+08:00 INFO 10480 --- [nio-8080-exec-1] com.example.aspect.CalcAspect : ******* @AfterReturning 返回通知 2023-09-02T22:37:34.643+08:00 INFO 10480 --- [nio-8080-exec-1] com.example.aspect.CalcAspect : ******** @After 后置通知 2023-09-02T22:37:34.644+08:00 INFO 10480 --- [nio-8080-exec-1] com.example.aspect.CalcAspect : ******** 环绕通知之后
通过将横切关注点(如日志、事务等)与业务逻辑分离,使得代码更加模块化,便于维护和扩展。
AOP可以将通用的功能抽取到一个切面中,然后在需要的地方进行引用,避免了重复编写相同的代码。
AOP可以将通用的功能封装成一个切面,然后在多个类或方法中进行引用,提高了代码的可重用性。
AOP可以在运行时动态地改变程序的行为,增强了代码的灵活性。
AOP可以将测试代码与业务逻辑分离,使得测试更加简单和方便。
在SpringBoot项目中,使用@Aspect可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性。
通过将横切关注点与业务逻辑分离,我们可以更专注于实现业务功能,同时避免重复编写相同的代码。
此外,AOP还可以提高代码的灵活性,使得我们在运行时可以动态地改变程序的行为。
总之,使用@Aspect是SpringBoot项目中的一个非常有用的特性,值得我们学习和掌握。
如果需要完整源码请关注公众号"架构殿堂" ,回复 "SpringBoot+AOP"即可获得
感谢您的支持和鼓励! 😊🙏
如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,系统架构, 分布式, java, GO, python, 游戏相关 等系列文章,一系列干货随时送达!