在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。
先引入依赖
代码语言:javascript复制<!-- aop依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
自定义注解
代码语言:javascript复制@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
创建数据库表和实体
数据库表:
代码语言:javascript复制DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (
`ID` int(11) NULL DEFAULT NULL,
`USERNAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`OPERATION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`TIME` int(11) NULL DEFAULT NULL,
`METHOD` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`PARAMS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`IP` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`CREATE_TIME` datetime(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
对应实体:
代码语言:javascript复制@Data
public class SysLog {
private Integer ID;
private String USERNAME;
private String OPERATION;
private Integer TIME;
private String METHOD;
private String PARAMS;
private String IP;
private Date CREATE_TIME;
}
保存日志的方法
代码语言:javascript复制@Component
@Mapper
public interface SysLogMapper {
@Insert("INSERT INTO `sys_log`(`ID`, `USERNAME`, `OPERATION`, `TIME`, `METHOD`, `PARAMS`, `IP`, `CREATE_TIME`) VALUES (#{ID}, #{USERNAME}, #{OPERATION}, #{TIME}, #{METHOD}, #{PARAMS}, #{IP}, #{CREATE_TIME})")
void saveSysLog(SysLog syslog);
}
切面和切点
代码语言:javascript复制@Aspect
@Component
public class LogAspect {
@Autowired
private SysLogMapper sysLogMapper;
@Pointcut("@annotation(com.example.lixj.annotation.Log)")
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 time = System.currentTimeMillis() - beginTime;
// 保存日志
saveLog(point, time);
return result;
}
private void saveLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = new SysLog();
Log logAnnotation = method.getAnnotation(Log.class);
if (logAnnotation != null) {
// 注解上的描述
sysLog.setOPERATION(logAnnotation.value());
}
// 请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMETHOD(className "." methodName "()");
// 请求的方法参数值
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
String params = "";
for (int i = 0; i < args.length; i ) {
params = " " paramNames[i] ": " args[i];
}
sysLog.setPARAMS(params);
}
// 获取request
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 设置IP地址
sysLog.setIP(request.getHeader("x-forwarded-for") == null ? request.getRemoteAddr() : request.getHeader("x-forwarded-for"));
// 模拟一个用户名
sysLog.setUSERNAME("lixj");
sysLog.setTIME((int) time);
sysLog.setID(new Random().nextInt());
//取当前时间
Date nowdate=new Date();
//转换时间格式
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sysLog.setCREATE_TIME(Timestamp.valueOf(simpleDate.format(nowdate)));
// 保存系统日志
sysLogMapper.saveSysLog(sysLog);
System.out.println(true);
}
}
测试
代码语言:javascript复制@RestController
public class TestLogController {
@Log("执行方法一")
@GetMapping(value = "/one")
public void method1(String name) {
}
@Log("执行方法二")
@GetMapping(value = "two")
public void method2() throws InterruptedException {
Thread.sleep(2000);
}
@Log("执行方法三")
@GetMapping(value = "three")
public void method3(String name, String age) {
}
}
启动项目,访问相关链接
查看数据库入表情况
Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/springboot学习-springbootaop记录用户操作日志