相关推荐recommended
SpringBoot简单使用切面类(@aspect注解)
作者:mmseoamin日期:2024-01-18

文章目录

      • 简介
      • 特点
      • 常用注解
        • @Aspect
        • @Pointcut
        • @Before
        • @After
        • @AfterReturning
        • @AfterThrowing
        • @Around
        • @Order
        • @EnableAspectJAutoProxy
        • 实例
          • 版本依赖
          • 导入依赖
          • CalcAspect
          • CalcServiceImpl
          • CalculatorController
          • 测试结果
          • 使用切面的好处
            • 代码解耦
            • 减少重复代码
            • 提高代码的可重用性
            • 增强代码的灵活性
            • 易于测试
            • 总结
            • 下载地址
            • 写在最后

              SpringBoot简单使用切面类(@aspect注解),579a429daf314744b995f37351b46548,第1张

              简介

              Spring Boot中的AOP(Aspect Oriented Programming, 面向切面编程)可以让我们实现一些与业务逻辑无关的功能,如日志、事务、安全等。


              特点

              1. 把这些跨切面关注点抽取出来,实现解耦。

              2. 使用切面承载这些功能的实现,而不污染业务逻辑。

              3. 在定义好的切入点Join Point,执行这些功能,比如方法调用前后。

              4. Spring AOP实现了动态代理,无需修改源码即可集成这些切面逻辑。

              5. 常用的切面功能有日志记录、性能统计、安全控制、事务管理等。

              6. 在Spring Boot中可以通过@Aspect、@Pointcut等注解声明切面。

              7. 通过@Before、@After、@Around定义Advice实现切面的功能。

              8. 使用方便,只需要添加注解配置,即可在应用中集成AOP。


              常用注解

              SpringBoot简单使用切面类(@aspect注解),image-20231110181719078,第2张

              @Aspect

              标注该类是一个切面类

              @Pointcut

              定义一个切入点,可以是一个规则表达式,也可以是一个注解等

              @Before

              前置通知,在目标方法调用前执行

              @After

              后置通知,在目标方法执行后调用

              @AfterReturning

              返回通知,在目标方法正常返回后调用

              @AfterThrowing

              异常通知,在目标方法抛出异常后调用

              @Around

              环绕通知,围绕目标方法执行

              @Order

              定义切面的优先级,值越小优先级越高

              @EnableAspectJAutoProxy

              开启Spring对AspectJ切面的支持


              实例

              版本依赖

              JDK17

              SpringBoot 3.1.0

              导入依赖
              4.0.0
              
                  org.springframework.boot
                  spring-boot-starter-parent
                  3.1.0
              
              org.example
              springboot-aspect
              1.0-SNAPSHOT
              
                  17
                  17
                  UTF-8
              
              
                  
                      org.springframework.boot
                      spring-boot-starter-aop
                  
                  
                      org.projectlombok
                      lombok
                  
                  
                      org.springframework.boot
                      spring-boot-starter-web
                  
              
              
              CalcAspect
              @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;
                  }
              }
              
              CalcServiceImpl
              /**
               * 计算服务实现
               * 微信公众号:架构殿堂
               */
              @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;
                  }
              }
              
              CalculatorController
              @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            : ******** 环绕通知之后
              

              使用切面的好处

              SpringBoot简单使用切面类(@aspect注解),image-20231110180739093,第3张

              1. 代码解耦

                通过将横切关注点(如日志、事务等)与业务逻辑分离,使得代码更加模块化,便于维护和扩展。

              2. 减少重复代码

                AOP可以将通用的功能抽取到一个切面中,然后在需要的地方进行引用,避免了重复编写相同的代码。

              3. 提高代码的可重用性

                AOP可以将通用的功能封装成一个切面,然后在多个类或方法中进行引用,提高了代码的可重用性。

              4. 增强代码的灵活性

                AOP可以在运行时动态地改变程序的行为,增强了代码的灵活性。

              5. 易于测试

                AOP可以将测试代码与业务逻辑分离,使得测试更加简单和方便。


              总结

              在SpringBoot项目中,使用@Aspect可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性。

              通过将横切关注点与业务逻辑分离,我们可以更专注于实现业务功能,同时避免重复编写相同的代码。

              此外,AOP还可以提高代码的灵活性,使得我们在运行时可以动态地改变程序的行为。

              总之,使用@Aspect是SpringBoot项目中的一个非常有用的特性,值得我们学习和掌握。


              下载地址

              如果需要完整源码请关注公众号"架构殿堂" ,回复 "SpringBoot+AOP"即可获得


              写在最后

              感谢您的支持和鼓励! 😊🙏

              如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,系统架构, 分布式, java, GO, python, 游戏相关 等系列文章,一系列干货随时送达!

              SpringBoot简单使用切面类(@aspect注解),csdn-end,第4张