فهرست منبع

update 优化 使用spring事件发布机制 重构登录日志与操作日志

疯狂的狮子li 2 سال پیش
والد
کامیت
4c8137daf2

+ 44 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/LogininforEvent.java

@@ -0,0 +1,44 @@
+package com.ruoyi.common.core.domain.event;
+
+import lombok.Data;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.Serializable;
+
+/**
+ * 登录事件
+ *
+ * @author Lion Li
+ */
+
+@Data
+public class LogininforEvent implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户账号
+     */
+    private String username;
+
+    /**
+     * 登录状态 0成功 1失败
+     */
+    private String status;
+
+    /**
+     * 提示消息
+     */
+    private String message;
+
+    /**
+     * 请求体
+     */
+    private HttpServletRequest request;
+
+    /**
+     * 其他参数
+     */
+    private Object[] args;
+
+}

+ 3 - 3
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/OperLogDTO.java → ruoyi-common/src/main/java/com/ruoyi/common/core/domain/event/OperLogEvent.java

@@ -1,4 +1,4 @@
-package com.ruoyi.common.core.domain.dto;
+package com.ruoyi.common.core.domain.event;
 
 import lombok.Data;
 
@@ -6,13 +6,13 @@ import java.io.Serializable;
 import java.util.Date;
 
 /**
- * 通用操作日志实体
+ * 操作日志事件
  *
  * @author Lion Li
  */
 
 @Data
-public class OperLogDTO implements Serializable {
+public class OperLogEvent implements Serializable {
 
     private static final long serialVersionUID = 1L;
 

+ 0 - 14
ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java

@@ -1,14 +0,0 @@
-package com.ruoyi.common.core.service;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * 通用 系统访问日志
- *
- * @author Lion Li
- */
-public interface LogininforService {
-
-    void recordLogininfor(String username, String status, String message,
-                          HttpServletRequest request, Object... args);
-}

+ 0 - 15
ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java

@@ -1,15 +0,0 @@
-package com.ruoyi.common.core.service;
-
-import com.ruoyi.common.core.domain.dto.OperLogDTO;
-import org.springframework.scheduling.annotation.Async;
-
-/**
- * 通用 操作日志
- *
- * @author Lion Li
- */
-public interface OperLogService {
-
-    @Async
-    void recordOper(OperLogDTO operLogDTO);
-}

+ 6 - 7
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java

@@ -4,8 +4,7 @@ import cn.hutool.core.lang.Dict;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.core.domain.dto.OperLogDTO;
-import com.ruoyi.common.core.service.OperLogService;
+import com.ruoyi.common.core.domain.event.OperLogEvent;
 import com.ruoyi.common.enums.BusinessStatus;
 import com.ruoyi.common.enums.HttpMethod;
 import com.ruoyi.common.helper.LoginHelper;
@@ -67,7 +66,7 @@ public class LogAspect {
         try {
 
             // *========数据库日志=========*//
-            OperLogDTO operLog = new OperLogDTO();
+            OperLogEvent operLog = new OperLogEvent();
             operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
             // 请求的地址
             String ip = ServletUtils.getClientIP();
@@ -87,8 +86,8 @@ public class LogAspect {
             operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
             // 处理设置注解上的参数
             getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
-            // 保存数据库
-            SpringUtils.getBean(OperLogService.class).recordOper(operLog);
+            // 发布事件保存数据库
+            SpringUtils.context().publishEvent(operLog);
         } catch (Exception exp) {
             // 记录本地异常日志
             log.error("异常信息:{}", exp.getMessage());
@@ -103,7 +102,7 @@ public class LogAspect {
      * @param operLog 操作日志
      * @throws Exception
      */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogDTO operLog, Object jsonResult) throws Exception {
+    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception {
         // 设置action动作
         operLog.setBusinessType(log.businessType().ordinal());
         // 设置标题
@@ -127,7 +126,7 @@ public class LogAspect {
      * @param operLog 操作日志
      * @throws Exception 异常
      */
-    private void setRequestValue(JoinPoint joinPoint, OperLogDTO operLog) throws Exception {
+    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog) throws Exception {
         String requestMethod = operLog.getRequestMethod();
         if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
             String params = argsArrayToString(joinPoint.getArgs());

+ 1 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java

@@ -18,7 +18,7 @@ import java.util.concurrent.ScheduledExecutorService;
  *
  * @author Lion Li
  */
-@EnableAsync
+@EnableAsync(proxyTargetClass = true)
 @Configuration
 public class AsyncConfig extends AsyncConfigurerSupport {
 

+ 8 - 3
ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java

@@ -7,11 +7,11 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.core.domain.event.LogininforEvent;
 import com.ruoyi.common.core.domain.dto.RoleDTO;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.domain.model.XcxLoginUser;
-import com.ruoyi.common.core.service.LogininforService;
 import com.ruoyi.common.enums.DeviceType;
 import com.ruoyi.common.enums.LoginType;
 import com.ruoyi.common.enums.UserStatus;
@@ -24,6 +24,7 @@ import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.redis.RedisUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -46,7 +47,6 @@ public class SysLoginService {
 
     private final ISysUserService userService;
     private final ISysConfigService configService;
-    private final LogininforService asyncService;
     private final SysPermissionService permissionService;
 
     @Value("${user.password.maxRetryCount}")
@@ -141,7 +141,12 @@ public class SysLoginService {
      * @return
      */
     private void recordLogininfor(String username, String status, String message) {
-        asyncService.recordLogininfor(username, status, message, ServletUtils.getRequest());
+        LogininforEvent logininforDTO = new LogininforEvent();
+        logininforDTO.setUsername(username);
+        logininforDTO.setStatus(status);
+        logininforDTO.setMessage(message);
+        logininforDTO.setRequest(ServletUtils.getRequest());
+        SpringUtils.context().publishEvent(logininforDTO);
     }
 
     /**

+ 23 - 5
ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java

@@ -4,9 +4,9 @@ import cn.dev33.satoken.secure.BCrypt;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
+import com.ruoyi.common.core.domain.event.LogininforEvent;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.RegisterBody;
-import com.ruoyi.common.core.service.LogininforService;
 import com.ruoyi.common.enums.UserType;
 import com.ruoyi.common.exception.user.CaptchaException;
 import com.ruoyi.common.exception.user.CaptchaExpireException;
@@ -15,6 +15,7 @@ import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.redis.RedisUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
@@ -31,7 +32,6 @@ public class SysRegisterService {
 
     private final ISysUserService userService;
     private final ISysConfigService configService;
-    private final LogininforService asyncService;
 
     /**
      * 注册
@@ -61,7 +61,7 @@ public class SysRegisterService {
         if (!regFlag) {
             throw new UserException("user.register.error");
         }
-        asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"), request);
+        recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"));
     }
 
     /**
@@ -77,12 +77,30 @@ public class SysRegisterService {
         String captcha = RedisUtils.getCacheObject(verifyKey);
         RedisUtils.deleteObject(verifyKey);
         if (captcha == null) {
-            asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"), request);
+            recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
             throw new CaptchaExpireException();
         }
         if (!code.equalsIgnoreCase(captcha)) {
-            asyncService.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"), request);
+            recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
             throw new CaptchaException();
         }
     }
+
+    /**
+     * 记录登录信息
+     *
+     * @param username 用户名
+     * @param status   状态
+     * @param message  消息内容
+     * @return
+     */
+    private void recordLogininfor(String username, String status, String message) {
+        LogininforEvent logininforDTO = new LogininforEvent();
+        logininforDTO.setUsername(username);
+        logininforDTO.setStatus(status);
+        logininforDTO.setMessage(message);
+        logininforDTO.setRequest(ServletUtils.getRequest());
+        SpringUtils.context().publishEvent(logininforDTO);
+    }
+
 }

+ 15 - 17
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java

@@ -6,8 +6,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.common.core.domain.event.LogininforEvent;
 import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.core.service.LogininforService;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.ip.AddressUtils;
@@ -16,6 +16,7 @@ import com.ruoyi.system.mapper.SysLogininforMapper;
 import com.ruoyi.system.service.ISysLogininforService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
@@ -33,22 +34,19 @@ import java.util.Map;
 @RequiredArgsConstructor
 @Slf4j
 @Service
-public class SysLogininforServiceImpl implements ISysLogininforService, LogininforService {
+public class SysLogininforServiceImpl implements ISysLogininforService {
 
     private final SysLogininforMapper baseMapper;
 
     /**
      * 记录登录信息
      *
-     * @param username 用户名
-     * @param status   状态
-     * @param message  消息
-     * @param args     列表
+     * @param logininforEvent 登录事件
      */
     @Async
-    @Override
-    public void recordLogininfor(final String username, final String status, final String message,
-                                 HttpServletRequest request, final Object... args) {
+    @EventListener
+    public void recordLogininfor(LogininforEvent logininforEvent) {
+        HttpServletRequest request = logininforEvent.getRequest();
         final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
         final String ip = ServletUtils.getClientIP(request);
 
@@ -56,27 +54,27 @@ public class SysLogininforServiceImpl implements ISysLogininforService, Logininf
         StringBuilder s = new StringBuilder();
         s.append(getBlock(ip));
         s.append(address);
-        s.append(getBlock(username));
-        s.append(getBlock(status));
-        s.append(getBlock(message));
+        s.append(getBlock(logininforEvent.getUsername()));
+        s.append(getBlock(logininforEvent.getStatus()));
+        s.append(getBlock(logininforEvent.getMessage()));
         // 打印信息到日志
-        log.info(s.toString(), args);
+        log.info(s.toString(), logininforEvent.getArgs());
         // 获取客户端操作系统
         String os = userAgent.getOs().getName();
         // 获取客户端浏览器
         String browser = userAgent.getBrowser().getName();
         // 封装对象
         SysLogininfor logininfor = new SysLogininfor();
-        logininfor.setUserName(username);
+        logininfor.setUserName(logininforEvent.getUsername());
         logininfor.setIpaddr(ip);
         logininfor.setLoginLocation(address);
         logininfor.setBrowser(browser);
         logininfor.setOs(os);
-        logininfor.setMsg(message);
+        logininfor.setMsg(logininforEvent.getMessage());
         // 日志状态
-        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
+        if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
             logininfor.setStatus(Constants.SUCCESS);
-        } else if (Constants.LOGIN_FAIL.equals(status)) {
+        } else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
             logininfor.setStatus(Constants.FAIL);
         }
         // 插入数据

+ 7 - 7
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java

@@ -5,15 +5,15 @@ import cn.hutool.core.util.ArrayUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.PageQuery;
-import com.ruoyi.common.core.domain.dto.OperLogDTO;
+import com.ruoyi.common.core.domain.event.OperLogEvent;
 import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.core.service.OperLogService;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.ip.AddressUtils;
 import com.ruoyi.system.domain.SysOperLog;
 import com.ruoyi.system.mapper.SysOperLogMapper;
 import com.ruoyi.system.service.ISysOperLogService;
 import lombok.RequiredArgsConstructor;
+import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
@@ -29,19 +29,19 @@ import java.util.Map;
  */
 @RequiredArgsConstructor
 @Service
-public class SysOperLogServiceImpl implements ISysOperLogService, OperLogService {
+public class SysOperLogServiceImpl implements ISysOperLogService {
 
     private final SysOperLogMapper baseMapper;
 
     /**
      * 操作日志记录
      *
-     * @param operLogDTO 操作日志信息
+     * @param operLogEvent 操作日志事件
      */
     @Async
-    @Override
-    public void recordOper(final OperLogDTO operLogDTO) {
-        SysOperLog operLog = BeanUtil.toBean(operLogDTO, SysOperLog.class);
+    @EventListener
+    public void recordOper(OperLogEvent operLogEvent) {
+        SysOperLog operLog = BeanUtil.toBean(operLogEvent, SysOperLog.class);
         // 远程查询操作地点
         operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
         insertOperlog(operLog);