SpringBoot 利用 AOP 完成日志收集打印工作
1.准备工作
idea 记得安装 lombok 插件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 用来解析json -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.8</version>
</dependency>
2. AopLog 类
@Aspect
@Component
@Slf4j
public class AopLog {
private static final String START_TIME = "request-start";
/**
* 切入点
*/
@Pointcut("execution(public * com.xx.controller.*Controller.*(..))")
public void log() {
}
/**
* 前置操作
*
* @param point 切入点
*/
@Before("log()")
public void beforeLog(JoinPoint point) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
// 这里我是用的 shiro 框架,你也可以根据你自己的方式获取当前用户
String username = (String) SecurityUtils.getSubject().getPrincipal();
log.info("【用户 Username】:{}", username);
log.info("【请求 URL】:{}", request.getRequestURL());
log.info("【请求 IP】:{}", request.getRemoteAddr());
log.info("【类名 Class】:{},【方法名 Method】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName());
log.info("【请求参数 Args】:{},", JSONUtil.toJsonStr(point.getArgs()));
Long start = System.currentTimeMillis();
request.setAttribute(START_TIME, start);
}
/**
* 环绕操作
*
* @param point 切入点
* @return 原方法返回值
* @throws Throwable 异常信息
*/
@Around("log()")
public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
Object result = point.proceed();
log.info("【返回值 Return】:{}", JSONUtil.toJsonStr(result));
log.info("-----------------------------------------------------------------");
return result;
}
}
3.@Pointcut 用法详解
1)execution(public * *(..))——表示匹配所有public方法
2)execution(* set*(..))——表示所有以“set”开头的方法
3)execution(* com.xyz.service.AccountService.*(..))——表示匹配所有AccountService接口的方法
4)execution(* com.xyz.service.*.*(..))——表示匹配service包下所有的方法
5)execution(* com.xyz.service..*.*(..))——表示匹配service包和它的子包下的方法
更详细的用法可以参考:https://blog.csdn.net/qq_18769269/article/details/80841734