1.引入依赖
implementation 'org.springframework.boot:spring-boot-starter-aop:3.3.0'
2.创建一个日志记录表
-- 操作日志表
create table operate_log(
id int unsigned primary key auto_increment comment 'ID',
operate_user int unsigned comment '操作人ID',
operate_time datetime comment '操作时间',
class_name varchar(100) comment '操作的类名',
method_name varchar(100) comment '操作的方法名',
method_params varchar(1000) comment '方法参数',
return_value varchar(2000) comment '返回值',
cost_time bigint comment '方法执行耗时, 单位:ms'
) comment '操作日志表';
3.创建对应的日志记录实体类
package com.yuzai.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {
private Integer id; //ID
private Integer operateUser; //操作人ID
private LocalDateTime operateTime; //操作时间
private String className; //操作类名
private String methodName; //操作方法名
private String methodParams; //操作方法参数
private String returnValue; //操作方法返回值
private Long costTime; //操作耗时
}
4.创建日志记录操作类
package com.yuzai.aop;
import com.alibaba.fastjson.JSONObject;
import com.yuzai.mapper.OperateLogMapper;
import com.yuzai.pojo.OperateLog;
import com.yuzai.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Arrays;
@Aspect//引入AOP
@Slf4j
@Component
public class LogAspect {
@Autowired
HttpServletRequest request;
@Autowired
OperateLogMapper operateLogMapper;
@Around("@annotation(com.yuzai.anno.Log)")//设置要作用于哪些方法上“@Log”为自定义注解,起标记作用
public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
//操作人ID
//获取请求头中的令牌,解析令牌
String jwt = request.getHeader("token");
Claims claims = JwtUtils.parseJWT(jwt);//阿里巴巴的fastjson工具
Integer operateUser = (Integer) claims.get("id");
//操作时间
LocalDateTime operateTime = LocalDateTime.now();
//操作类名
String className = joinPoint.getTarget().getClass().getName();
//操作方法名
String methodName = joinPoint.getSignature().getName();
//操作方法参数
Object[] args = joinPoint.getArgs();
String methodParams = Arrays.toString(args);
//调用原始目标方法运行
Long begin = System.currentTimeMillis();
Object result = joinPoint.proceed();
Long end = System.currentTimeMillis();
//方法返回值
String returnValue = JSONObject.toJSONString(result);
//操作耗时
Long costTime = end-begin;
//记录操作日志
OperateLog operateLog = new OperateLog(null, operateUser, operateTime, className, methodName, methodParams, returnValue, costTime);
//将数据插入到数据库中
operateLogMapper.insert(operateLog);
log.info("aop操作日志:{}", operateLog);
return result;
}
}
5.创建@Tag注解
package com.yuzai.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//运行时保留
@Target(ElementType.METHOD)//作用于方法
public @interface Log {}
6.使用自定义的@Tag注解标记要记录日志的方法
通常只标记增删改,对数据造成影响的操作