spring|SpringAop日志记录

spring日志记录(使用切面方式记录) 执行流程图 spring|SpringAop日志记录
文章图片

1. 创建pojo类

@Data @Table(name = "tb_operate_record") public class OperateRecord { @Id private String id; //记录请求时间 @Column(name = "record_time") private Date recordTime; //操作者 private String username; //请求IP @Column(name = "request_ip") private String requestIp; //操作类型, true操作记录 false异常记录 private Boolean type; //请求的方法 @Column(name = "request_method") private String requestMethod; //自定义注解中的name @Column(name = "request_annotation_name") private String requestAnnotationName; //异常描述 @Column(name = "exception_msg") private String exceptionMsg; }

/** * 系统日志事件 */ public class OperateRecordEvent extends ApplicationEvent { /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public OperateRecordEvent(Object source) { super(source); } }

2.创建自定义注解
@Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface LogRecord { String value() default ""; }

3.创建监听器
/** * 注解形式的监听,异步监听日志事件 */ @Component @Slf4j public class OperateRecordListener { @Autowired private OperateRecordService operateRecordService; @Async @Order @EventListener(OperateRecordEvent.class) public void saveOperateRecord(OperateRecordEvent event) { OperateRecord operateRecord = (OperateRecord) event.getSource(); //保存日志 operateRecordService.save(operateRecord); } }

4.创建切面类
/** * 操作日志切面 * 且体面注解得到请求数据 --> 发布监听事件 --> 异步监听日志入库 */ @Component @Aspect@Slf4j public class OperateAspect { // 创建OperateRecord对象 private OperateRecord operateRecord = new OperateRecord(); @Autowired private ApplicationContext applicationContext; @Autowired private RsaKeyProperties properties; /** * 定义controller切入点拦截规则,拦截LogRecord注解的方法 */ @Pointcut("@annotation(com.mayday.common.api.LogRecord)") public void operateAspect() {} /** * 拦截控制层的操作日志 * * @param joinPoint */ @Before(valuehttps://www.it610.com/article/= "https://www.it610.com/article/operateAspect()") public void recordLog(JoinPoint joinPoint) throws Exception { //获取request对象 HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); operateRecord.setId(String.valueOf(new IdWorker().nextId())); operateRecord.setRecordTime(new Date()); operateRecord.setRequestIp(request.getRemoteHost()); String username = this.getUsernameByRequest(request); operateRecord.setUsername(StringUtils.isNotEmpty(username) ? username : "anonymous"); operateRecord.setRequestMethod(joinPoint.getTarget().getClass().getSimpleName() + "." + joinPoint.getSignature().getName()); operateRecord.setRequestAnnotationName(this.getControllerMethodDescription(joinPoint)); }/** * 返回通知 * * @param ret */ @AfterReturning(returning = "ret", pointcut = "operateAspect()") public void doAfterReturning(Object ret) { //处理完请求,返回内容 Result result = Convert.convert(Result.class, ret); if (result.getFlag()) { //正常返回 operateRecord.setType(true); } else { operateRecord.setType(false); String resultMsg = result.getMessage(); if ((StringUtils.length(resultMsg) > 10)) { operateRecord.setExceptionMsg(resultMsg.substring(0, 10)); } else { operateRecord.setExceptionMsg(resultMsg); } } //发布事件 applicationContext.publishEvent(new OperateRecordEvent(operateRecord)); }/** * 异常通知 * * @param e */ @AfterThrowing(pointcut = "operateAspect()", throwing = "e") public void doAfterThrowable(Throwable e) { //异常 operateRecord.setType(false); operateRecord.setExceptionMsg(e.getMessage()); //发布事件 applicationContext.publishEvent(new OperateRecordEvent(operateRecord)); }/** * 通过request对象获取用户名 * * @param request * @return */ private String getUsernameByRequest(HttpServletRequest request) { String header = request.getHeader("Authorization"); if (StringUtils.isNotEmpty(header) && header.startsWith("Bearer ")) { String token = header.replace("Bearer ", ""); Payload payload = JwtUtils.genInfoFromToken(token, properties.getPublicKey(), User.class); return payload.getUserInfo().getUsername(); } return null; }/** * 获取方法上对应注解的value * * @param joinPoint * @return * @throws Exception */ private String getControllerMethodDescription(JoinPoint joinPoint) throws Exception { //获取连接点目标类型 String targetName = joinPoint.getTarget().getClass().getName(); //获取连接点签名的方法名 String methodName = joinPoint.getSignature().getName(); //获取连接点参数 Object[] args = joinPoint.getArgs(); //根据连接点类的名字获取指定类 Class targetClass = Class.forName(targetName); //获取类里面的方法 Method[] methods = targetClass.getMethods(); String valuehttps://www.it610.com/article/= ""; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] cls = method.getParameterTypes(); if (cls.length == args.length) { value = https://www.it610.com/article/method.getAnnotation(LogRecord.class).value(); break; } } } return value; } }

5.在相应的类上加上注解 【spring|SpringAop日志记录】spring|SpringAop日志记录
文章图片

    推荐阅读