• 使用AOP做日志切面


    使用AOP对所有请求接口做日志打印

    1. 引入spring-boot-starter-aop maven依赖

      
          org.springframework.boot
          spring-boot-starter-aop
      
      
      • 1
      • 2
      • 3
      • 4
    2. 创建日志切面类

      @Aspect	// 添加Aspect注解
      @Component	// 注册为SpringBean
      public class LogAspect {
          
          private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
          
          // 定义该切面的切入点为allCtlMethod(), 需要被切入的方法为: ctl这个包下的所有带@RequestMapping, @PostMapping, @GetMapping的方法
          @Pointcut("execution(* com.welldone.calcprogram.ctl..*.*(..)) "
                  + "&& "
                  + "(@annotation(org.springframework.web.bind.annotation.RequestMapping)"
                  + "|| @annotation(org.springframework.web.bind.annotation.PostMapping)"
                  + "|| @annotation(org.springframework.web.bind.annotation.GetMapping)"
                  + ")"
          )
          public void allCtlMethod() {}
      	
          
          /** allCtlMethod()指定的目标方法执行前执行before方法
           * @param call 切入点,即目标方法
           */
          @Before("allCtlMethod()")
          public void before(JoinPoint call) {
              if (log.isInfoEnabled()) {
                  String clazzName = call.getTarget().getClass().getName();
                  String methodName = call.getSignature().getName();
                  Object[] args = call.getArgs();
                  StringBuffer sb = new StringBuffer()
                          .append("[start]").append(clazzName).append(".").append(methodName).append(", args: ");
                  for (Object arg : args) {
                      sb.append(arg);
                  }
                  log.info(sb.toString());
              }
          }
          
      	/** allCtlMethod()指定的目标方法返回后执行afterReturning方法
      		returning的值要和Object的参数名obj一致
           * @param call 切入点,即目标方法
           * @param obj 目标方法返回值
           */
          @AfterReturning(pointcut = "allCtlMethod()", returning = "obj")
          public void afterReturning(JoinPoint call, Object obj) {
              if (log.isInfoEnabled()) {
                  String clazzName = call.getTarget().getClass().getName();
                  String methodName = call.getSignature().getName();
                  String output = obj != null ? obj.toString() : "";
                  log.info("[end]" + clazzName + "." + methodName + ", returnValue: " + output);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
    3. 测试

      访问Controller中其中一个请求接口,打印日志如下:

      2022-12-03 17:29:26.584  INFO 247728 --- [nio-8080-exec-4] c.w.calcprogram.ext.aspect.LogAspect     : [start]com.welldone.calcprogram.ctl.CalcController.calc, args: 1997-04-14 00:00:00
      2022-12-03 17:29:26.584  INFO 247728 --- [nio-8080-exec-4] c.w.calcprogram.ctl.CalcController       : 执行CalcController.calc
      2022-12-03 17:29:26.584  INFO 247728 --- [nio-8080-exec-4] c.w.calcprogram.ext.aspect.LogAspect     : [end]com.welldone.calcprogram.ctl.CalcController.calc, returnValue: 1997-04-14 00:00:00
      
      • 1
      • 2
      • 3

    补充要点:

    @Before, @After, @Around, @AfterReturning, @AfterThrowing区别

    @Before是在所拦截方法执行之前执行一段逻辑。
    @After 是在所拦截方法执行之后执行一段逻辑(不论是正常返回还是异常退出)。
    @Around是可以同时在所拦截方法的前后执行一段逻辑。
    @AfterReturning 正常完成后执行的通知,不包括抛出异常的情况。
    @AfterThrowing 抛出异常后通知,在方法抛出异常退出时执行的通知。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @Before, @After, @Around, @AfterReturning, @AfterThrowing执行顺序:

    正常返回时,走AfterReturning
    @Around前置逻辑 -> @Before -> 执行目标方法 -> @Around后置逻辑 -> @After -> @AfterReturning
    
    抛异常时,走AfterThrowing
    @Around前置逻辑 -> @Before -> 执行目标方法 -> @Around后置逻辑 -> @After -> @AfterThrowing
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @Pointcut 切入点,指的是需要被增强的目标方法, @Pointcut中的execution表达式为切入点表达式。

  • 相关阅读:
    java计算机毕业设计ssm党支部在线学习
    删除表数据
    吴恩达—机器学习的六个核心算法
    Golang标准库
    面试题整理:防抖函数的应用场景和实现方式?
    金仓数据库 KDTS 迁移工具使用指南 (4. BS 版使用说明)
    pcd点云格式介绍
    冯诺依曼体系各硬件工作原理解析
    No7.【spring-cloud-alibaba】用户登录密码加密、密码登录模式添加验证码校验
    虚拟机ubuntu22.04找不到ttyUSB*端口
  • 原文地址:https://blog.csdn.net/weixin_40927846/article/details/128166815