文章目录
1、背景
最近在做 SpringBoot 的项目,里面需要记录 Controller 和 Feign 的请求响应日志到数据库。
AOP 用到的技术是动态代理,SpringBoot 的 AOP 主要是基于 aspectj 技术。
动态代理技术相关的知识可以参考:https://cloud.tencent.com/developer/article/1461796
SpringBoot AOP 处理类共有几个要素,分别是:
<!--引入AOP依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
下面跟随我一起实践一下AOP的强大功能。
2、单切:记录Controller日志
代码:https://github.com/leexiangg/aop.git
2.1、切入点配置
对 controller 包下面所有类的所有方法做切入
private final String pointcut = "execution(* com.limouren.aop.controller..*(..))";
@Pointcut(value = pointcut)
public void log() {
}
2.2、方法执行前
可以通过 JoinPoint 获取类和方法的信息,通过 Request 获取请求信息。
@Before(value = "log()")
public void before(JoinPoint joinPoint) throws Throwable {
msgLog = new MsgLog();
try {
// 请求时间
msgLog.setReqTime(new Date());
// 请求数据头
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 请求类型
msgLog.setReqType(request.getMethod());
// 请求URL
msgLog.setReqUrl(request.getRequestURI());
// ... 其他赋值部分省略
// 请求IP
msgLog.setReqIp(getIpAddress(request));
// 请求数据
String reqmsg = JSON.toJSON(joinPoint.getArgs()).toString();
msgLog.setReqMsg(reqmsg);
// 打印文件日志
LoggerFactory.getLogger(msgLog.getClassName()).info(msgLog.getReqIp() + " " + msgLog.getReqType() + "请求 " + msgLog.getReqUrl() + ",请求信息:" + reqmsg);
} catch (Exception e) {
e.printStackTrace();
}
}
2.3、方法执行后
可以获取到方法执行成功的返回信息
@AfterReturning(returning = "result", pointcut = "log()")
public Object afterReturn(Object result) {
try {
if(msgLog != null) {
if(result != null && result instanceof ResponseEntity) {
if(HttpStatus.OK.equals(((ResponseEntity) result).getStatusCode())) {
msgLog.setRspStatus("成功");
} else {
msgLog.setRspStatus("失败");
}
}
// 耗时
if(msgLog.getReqTime() != null)
msgLog