SpringBoot使用AOP实现数据库日志表添加
sql脚本,生成表文件
-- mcams.t_log definition CREATE TABLE `t_log` ( `log_id` int NOT NULL AUTO_INCREMENT COMMENT '日志编号', `user_id` int NOT NULL COMMENT '操作人id', `operation` varchar(128) NOT NULL COMMENT '用户操作', `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '操作的方法', `params` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '方法的参数', `ip` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '用户的ip', `create_time` timestamp NULL DEFAULT NULL COMMENT '操作时间', `cost_time` int DEFAULT NULL COMMENT '花费时间', PRIMARY KEY (`log_id`) ) ENGINE=InnoDB AUTO_INCREMENT=189 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
导入依赖
我使用的是 Spring Boot 所以需要引入 spring aop 的 starter
如果是使用 spring 框架的,引入 spring-aop 即可
org.springframework.boot spring-boot-starter-aop
创建ThreadLocalUtils 工具类
public class ThreadLocalUtils {
private final static ThreadLocal userThreadLocal = new ThreadLocal<>();
public static void set(Integer uid){
userThreadLocal.set(uid);
}
public static Integer get(){
return userThreadLocal.get();
}
}
创建接口
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ILog {
String value() default "";
}
配置AOP
package com.data.datarestore.aop;
import com.data.datarestore.entity.TLog;
import com.data.datarestore.service.TLogService;
import org.aspectj.lang.reflect.MethodSignature;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.rmi.runtime.Log;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Date;
@Aspect
@Component
@RequiredArgsConstructor
public class LogAspect {
private final TLogService logService;
@Pointcut("@annotation(com.data.datarestore.aop.ILog)")
public void pointcut() {
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) {
Object result = null;
long beginTime = System.currentTimeMillis();
try {
result = point.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
long costTime = System.currentTimeMillis() - beginTime;
saveLog(point, costTime);
return result;
}
private void saveLog(ProceedingJoinPoint point, Long costTime) {
// 通过 point 拿到方法签名
MethodSignature methodSignature = (MethodSignature) point.getSignature();
// 通过方法签名拿到被调用的方法
Method method = methodSignature.getMethod();
TLog log = new TLog();
// 通过方法区获取方法上的 ILog 注解
ILog logAnnotation = method.getAnnotation(ILog.class);
if (logAnnotation != null) {
log.setOperation(logAnnotation.value());
}
String className = point.getTarget().getClass().getName();
String methodName = methodSignature.getName();
log.setMethod(className + "." + methodName + "()");
// 获取方法的参数
Object[] args = point.getArgs();
LocalVariableTableParameterNameDiscoverer l = new LocalVariableTableParameterNameDiscoverer();
String[] parameterNames = l.getParameterNames(method);
if (args != null && parameterNames != null) {
StringBuilder param = new StringBuilder();
for (int i = 0; i < args.length; i++) {
param.append(" ").append(parameterNames[i]).append(":").append(args[i]);
}
log.setParams(param.toString());
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
log.setIp(request.getRemoteAddr());
// login方法调这个,传入登录用户的uid
// ThreadLocalUtils.set(uid);
log.setUserId(ThreadLocalUtils.get());
log.setCostTime(costTime.intValue());
log.setCreateTime(new Date());
logService.insertSelective(log);
}
}
测试类使用
package com.data.datarestore.aop;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("web")
@RequiredArgsConstructor
public class Test {
@ILog("通过角色获取部门列表")
@GetMapping("")
public void test(){
System.out.println("aaa");
}
}
暑期编程PK赛
得CSDN机械键盘等精美礼品!


