• 使用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表达式为切入点表达式。

  • 相关阅读:
    Hbuilder x学习1-Hbuilder x下载
    [附源码]计算机毕业设计JAVA科院垃圾分类系统
    如何在Windows系统中安装5.7.26版本的MySQL?
    HTML5七夕情人节表白网页制作【唯美满天星3D相册】HTML+CSS+JavaScript
    【云原生 | Kubernetes 实战】06、Pod高级实战:基于污点、容忍度、亲和性的多种调度策略(下)
    国内数据防泄漏产品选型指南
    三视角:定位、自省与多维
    SPL工业智能:发现时序数据的异常
    【分布式系统】业务拆分后数据库将面临什么问题
    LVS + KeepAlived实现高可用负载均衡
  • 原文地址:https://blog.csdn.net/weixin_40927846/article/details/128166815