【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志

1. 添加依赖


<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starter-aopartifactId>
dependency>

2. 定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActionLog {

    String action() default "";

    String topic() default "";

}

3. 定义切面类

import com.cnhqd.authcenter.framework.common.utils.IpUtils;
import com.cnhqd.authcenter.framework.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Aspect
@Component
public class ActionLogAspect {

  @Pointcut("@annotation(com.cnhqd.authcenter.framework.common.log.ActionLog)")
  public void actionLog() {

  }

  /*** 在切点之前织入* @param joinPoint* @throws Throwable*/
  @Before("actionLog()")
  public void doBefore(JoinPoint joinPoint) throws Exception {
    // 开始打印请求日志
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();// 打印请求相关参数
    log.info("=================== Start ====================");
    // 打印请求url
    log.info("URL            : {}", request.getRequestURL().toString());
    // 打印Httpmethod
    log.info("HTTP Method    : {}", request.getMethod());
    // 打印调用 controller 的全路径以及执行方法
    log.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
    // 打印请求的IP
    log.info("IP             : {}", IpUtils.getIpAddr(request));
    // 打印请求入参
    log.info("Request Args   : {}", JsonUtils.toJsonString(joinPoint.getArgs()));
    ActionLog annotation = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(ActionLog.class);
    log.info("topic          :{}", annotation.topic());
    log.info("action         :{}", annotation.action());
  }

  @AfterReturning("actionLog()")
  public void afterReturning(){
    log.info("result        :{}", 200);
    log.info("=================== End ====================");
  }

  @AfterThrowing(pointcut = "actionLog()", throwing = "ex")
  public void afterThrowing(Throwable ex) {
    log.info("result        :{}", ex.getMessage());
    log.info("=================== End ====================");
  }

}

各注解说明:

@Aspect:声明该类为一个注解类;  

@Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为某个 package 下的方法,也可以是自定义注解等;  

@Before: 在切点之前,织入相关代码;  

@After: 在切点之后,织入相关代码;  

@AfterReturning: 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;  

@AfterThrowing: 用来处理当织入的代码抛出异常后的逻辑处理;  

@Around: 在切入点前后织入代码,并且可以自由的控制何时执行切点;

4. 简单测试

编写测试controller

import com.cnhqd.authcenter.framework.common.log.ActionLog;
import com.cnhqd.authcenter.system.vo.SysAccountLoginVO;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("testAops")
public class TestAopsController {

    @GetMapping("get")
    @ActionLog(action = "get", topic = "测试AOP")
    public String get(String id) {
        return id;
    }

    @PostMapping("post")
    @ActionLog(action = "post", topic = "测试AOP")
    public String post(@RequestBody SysAccountLoginVO vo) {
        System.out.println(JsonUtils.toJsonString(vo));
        return "success";
    }

    @GetMapping("getEx")
    @ActionLog(action = "getEx", topic = "测试AOP")
    public String getEx() {
        throw new RuntimeException("getEx-这里是异常输出测试");
    }

    @PostMapping("postEx")
    @ActionLog(action = "postEx", topic = "测试AOP")
    public String postEx() {
        throw new RuntimeException("postEx-这里是异常输出测试");
    }
}

使用postman发送对应请求,观察控制台输出
【工作记录】springboot集成aop实现日志@20230918_第1张图片
【工作记录】springboot集成aop实现日志@20230918_第2张图片
【工作记录】springboot集成aop实现日志@20230918_第3张图片
【工作记录】springboot集成aop实现日志@20230918_第4张图片
【工作记录】springboot集成aop实现日志@20230918_第5张图片
【工作记录】springboot集成aop实现日志@20230918_第6张图片
【工作记录】springboot集成aop实现日志@20230918_第7张图片
【工作记录】springboot集成aop实现日志@20230918_第8张图片
可以看到日志可以正常输出,如有必要保存相关数据到数据库即可。

你可能感兴趣的:(spring,boot,后端,java,日志,AOP)