Spring Event事件通知机制-日志整合实例
本学习笔记主要是介绍Spring中的事件通知是如何实现的,并且对项目中如何使用spring event 实现日志监听
监听者模式
学习spring的事件通知机制肯定要先了解监听者模式(监听者模式和观察者模式有什么区别?)
监听者模式包含了一个监听者Listener与之对应的事件Event,还有一个事件发布者EventPublish,过程就是EventPublish发布一个事件,被监听者捕获到,然后执行事件相应的方法 ----jwfy 简书
日志事件定义
@Getter @AllArgsConstructor public class SysLogEvent { private final SysLog sysLog; }
异步事件监听
@Slf4j @AllArgsConstructor public class SysLogListener { // 远程日志类 private final RemoteLogService remoteLogService; @Async @Order @EventListener(SysLogEvent.class) public void saveSysLog(SysLogEvent event) { SysLog sysLog = event.getSysLog(); remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN); } }
日志注解类
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SysLog { /** * 描述 * * @return {String} */ String value(); }
发送异步日志事件
@Slf4j @Aspect @AllArgsConstructor public class SysLogAspect { private final ApplicationEventPublisher publisher; @SneakyThrows @Around("@annotation(sysLog)") public Object around(ProceedingJoinPoint point, SysLog sysLog) { String strClassName = point.getTarget().getClass().getName(); String strMethodName = point.getSignature().getName(); log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName); com.wildcatcloud.wildcat.admin.api.entity.SysLog sysLogVo = SysLogUtils.getSysLog(); sysLogVo.setTitle(sysLog.value()); // 发送异步日志事件 Long startTime = System.currentTimeMillis(); Object obj = point.proceed(); Long endTime = System.currentTimeMillis(); sysLogVo.setTime(endTime - startTime); publisher.publishEvent(new SysLogEvent(logVo)); return obj; } }
日志拓展
@UtilityClass public class SysLogUtils { public SysLog getSysLog() { HttpServletRequest request = ((ServletRequestAttributes) Objects .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); SysLog sysLog = new SysLog(); sysLog.setCreateBy(Objects.requireNonNull(getUsername())); sysLog.setType(CommonConstants.STATUS_NORMAL); sysLog.setRemoteAddr(HttpUtil.getClientIP(request)); sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI())); sysLog.setMethod(request.getMethod()); sysLog.setUserAgent(request.getHeader("user-agent")); sysLog.setParams(HttpUtil.toParams(request.getParameterMap())); sysLog.setServiceId(getClientId()); return sysLog; }
}
使用
/** * 新增菜单 * * @param sysMenu 菜单信息 * @return success/false */ @SysLog("新增菜单") @PostMapping public R save(@Valid @RequestBody SysMenu sysMenu) { return new R<>(sysMenuService.save(sysMenu)); }