java注解日志记录到数据库
1. pom 添加依赖包
<!-- 添加 aop 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 配置文件 application.yml 添加
spring:
aop:
auto: true
3 创建实体类
package com.spring4all.entity;import java.io.Serializable;
import java.util.Date;/**
@author shafei
@version 1.0
@date 10:28 2019/9/7
@fun
*/
public class SysLogDO implements Serializable {
private Long id;private String username; //用户名
private String operation; //操作
private String method; //方法名
private String params; //参数
private String ip; //ip 地址
private Date createDate; //操作时间
public Long getId() {
return id;
}public void setId(Long id) {
this.id = id;
}public String getUsername() {
return username;
}public void setUsername(String username) {
this.username = username;
}public String getOperation() {
return operation;
}public void setOperation(String operation) {
this.operation = operation;
}public String getMethod() {
return method;
}public void setMethod(String method) {
this.method = method;
}public String getParams() {
return params;
}public void setParams(String params) {
this.params = params;
}public String getIp() {
return ip;
}public void setIp(String ip) {
this.ip = ip;
}public Date getCreateDate() {
return createDate;
}public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
4. 使用 spring 的 aop 技术切到自定义注解上,所以先创建一个自定义注解类
package com.spring4all.config.intercepors;
import java.lang.annotation.*;
/**
- @author shafei
- @version 1.0
- @date 10:06 2019/9/7
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD 是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface MyLog {
String value() default "";
}
5.AOP 实现:
package com.spring4all.config;import com.alibaba.fastjson.JSON;
import com.spring4all.config.intercepors.MyLog;
import com.spring4all.entity.SysLogDO;
import com.spring4all.service.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
/**
@author shafei
@version 1.0
@date 10:08 2019/9/7
fun:
*/
@Aspect
@Component
public class SysLogAspect {@Autowired
private SysLogService sysLogService;//定义切点 @Pointcut
//在注解的位置切入代码
@Pointcut("@annotation( com.spring4all.config.intercepors.MyLog)")
public void logPoinCut() {
}//切面 配置通知
@AfterReturning("logPoinCut()")
public void saveSysLog(JoinPoint joinPoint) {
System.out.println("切面。。。。。");
//保存日志
SysLogDO sysLog = new SysLogDO();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">从切面织入点处通过反射机制获取织入点处的方法</span> MethodSignature signature =<span style="color: rgba(0, 0, 0, 1)"> (MethodSignature) joinPoint.getSignature(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取切入点所在的方法</span> Method method =<span style="color: rgba(0, 0, 0, 1)"> signature.getMethod(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取操作</span> MyLog myLog = method.getAnnotation(MyLog.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (myLog != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { String value </span>=<span style="color: rgba(0, 0, 0, 1)"> myLog.value(); sysLog.setOperation(value);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">保存获取的操作</span>
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取请求的类名</span> String className =<span style="color: rgba(0, 0, 0, 1)"> joinPoint.getTarget().getClass().getName(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取请求的方法名</span> String methodName =<span style="color: rgba(0, 0, 0, 1)"> method.getName(); sysLog.setMethod(className </span>+ "." +<span style="color: rgba(0, 0, 0, 1)"> methodName); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">请求的参数</span> Object[] args =<span style="color: rgba(0, 0, 0, 1)"> joinPoint.getArgs(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将参数所在的数组转换成json</span> String params =<span style="color: rgba(0, 0, 0, 1)"> JSON.toJSONString(args); sysLog.setParams(params); sysLog.setCreateDate(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date()); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取用户名</span> sysLog.setUsername("shafei"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取用户ip地址
// HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
sysLog.setIp("192.168.3.11");</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用service保存SysLog实体类到数据库
// sysLogService.save(sysLog);
System.out.println("将日志记录到数据库");
}
}
6. 接下来就可以在需要监控的方法上添加 aop 的自定义注解
格式为 @+ 自定义注解的类名
@Controller @RequestMapping("/test") public class UserController {@MyLog(value </span>= "测试一下"<span style="color: rgba(0, 0, 0, 1)">) @GetMapping(</span>"/test"<span style="color: rgba(0, 0, 0, 1)">) @ResponseBody </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String test(){ </span><span style="color: rgba(0, 0, 255, 1)">return</span> "test"<span style="color: rgba(0, 0, 0, 1)">; }
}
说明:
记录日志的服务层接口 SysLogService 需要另外写,这个应该都会写;
参考 https://www.jianshu.com/p/d0bbdf1974bd