Springboot自定义注解+AOP实现日志管理
前言
在写Aurora这个项目之前,我是通过拦截器去记录用户操作日志,而这里讲解如何使用AOP配合自定义注解去实现用户日志记录,使用拦截器的方式,下一章贴出
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
部分配置文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/log
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
自定义log注解
定义一个方法级别的@Log注解,用于标注需要监控的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
创建实体类
创建 repository @Repository public interface SysLogRepo extends JpaRepository<SysLog,Long>{ }
切面和切点
定义一个LogAspect类,使用@Aspect标注让其成为一个切面,切点为使用@Log注解标注的方法,使用@Around环绕通知,部门工具代码,这里就不贴出了,可以到源码中查看
@Slf4j
@Aspect
@Component
public class LogAspect {
@Autowired
private SysLogRepo sysLogRepo;
@Pointcut("@annotation(me.zhengjie.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;
}
public 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();
String username = null;
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 = HttpContextUtils.getHttpServletRequest();
// 设置IP地址
sysLog.setIp(AddressUtils.getIpAddr(request));
sysLog.setLocation(AddressUtils.getCityInfo(sysLog.getIp()));
//模拟一个用户名
sysLog.setUsername("admin");
sysLog.setTime((int) time);
sysLogRepo.save(sysLog);
}
}
项目结构如下
测试 编写TestController
@RestController
public class TestController {
@Autowired
private SysLogRepo sysLogRepo;
@Log("记录测试")
@GetMapping(value = "/test")
public String test1(String test){
return test;
}
@GetMapping(value = "/list")
public ModelAndView list(Model model){
List<SysLog> sysLogs = sysLogRepo.findAll();
model.addAttribute("sysLogs",sysLogs);
return new ModelAndView("/index");
}
}
依次访问: localhost:8080/test?test=123 localhost:8080/list 项目源码 github:https://github.com/dqjdda/SpringBoot_All 码云:https://gitee.com/hgpt/SpringBoot_All
开源后台管理系统 欢迎体验Aurora
github: https://github.com/dqjdda/Aurora
码云:
