SpringBoot利用Aop打印入参出参日志
前言
以前写代码不会用Aop的时候,记录入参出参的日志打印都是在Controller中完成的,每个Controller的方法开始之前先打印个日志,然后方法返回之前再打印一行日志,虽然以前也感觉到这个代码比较冗余,也知道Aop可以实现日志打印,但是思维固话了,也习惯了,也就得过且过了。
直到接到上任同事留下的项目,日志没有对入参出参做统一的打印,线上出现问题的时候定位比较困难,所以觉得对他的代码加上统一的入参出参日志,由于Controller比较多,不想一个个的加,所以就想到了利用Aop来实现这个功能
首先在SpringBoot的项目里面引入Aop的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
下面的类可以直接拿来用,只需要改下切入点的类名的路径
@Aspect
@Component
@Slf4j
public class LogAspect {
//用来记录请求进入的时间,防止多线程时出错,这里用了ThreadLocal
ThreadLocal<Long> startTime = new ThreadLocal<>();
/**
* 定义切入点,controller下面的所有类的所有公有方法,这里需要更改成自己项目的
*/
@Pointcut("execution(public * com.tk.riskanalysis.controller..*.*(..))")
public void requestLog(){};
/**
* 方法之前执行,日志打印请求信息
* @param joinPoint joinPoint
*/
@Before("requestLog()")
public void doBefore(JoinPoint joinPoint) {
startTime.set(System.currentTimeMillis());
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
//打印当前的请求路径
log.info("RequestMapping:[{}]",request.getRequestURI());
//这里是从token中获取用户信息,打印当前的访问用户,代码不通用
/* String token = request.getHeader(JwtUtils.TOKEN_HEADER);
if (token != null && token.startsWith(JwtUtils.TOKEN_PREFIX)) {
token = token.replace(JwtUtils.TOKEN_PREFIX, "");
String username = JwtUtils.getUsername(token);
log.info("Current User is:[{}]",username);
}*/
//打印请求参数,如果需要打印其他的信息可以到request中去拿
log.info("RequestParam:{}", Arrays.toString(joinPoint.getArgs()));
}
/**
* 方法返回之前执行,打印才返回值以及方法消耗时间
* @param response 返回值
*/
@AfterReturning(returning = "response",pointcut = "requestLog()")
public void doAfterRunning(Object response) {
//打印返回值信息
log.info("Response:[{}]",response );
//打印请求耗时
log.info("Request spend times : [{}ms]",System.currentTimeMillis()-startTime.get());
}
}