Bläddra i källkod

update 优化 异步工厂重写 使用 spring 异步处理

疯狂的狮子li 3 år sedan
förälder
incheckning
8349e631d2

+ 3 - 5
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java

@@ -8,10 +8,8 @@ import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.enums.BusinessStatus;
 import com.ruoyi.common.enums.HttpMethod;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
+import com.ruoyi.framework.web.service.AsyncService;
 import com.ruoyi.framework.web.service.TokenService;
 import com.ruoyi.system.domain.SysOperLog;
 import org.aspectj.lang.JoinPoint;
@@ -93,7 +91,7 @@ public class LogAspect
             SysOperLog operLog = new SysOperLog();
             operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
             // 请求的地址
-            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+            String ip = ServletUtils.getClientIP();
             operLog.setOperIp(ip);
             // 返回参数
             operLog.setJsonResult(JSON.toJSONString(jsonResult));
@@ -118,7 +116,7 @@ public class LogAspect
             // 处理设置注解上的参数
             getControllerMethodDescription(joinPoint, controllerLog, operLog);
             // 保存数据库
-            AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
+			SpringUtils.getBean(AsyncService.class).recordOper(operLog);
         }
         catch (Exception exp)
         {

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

@@ -2,6 +2,8 @@ package com.ruoyi.framework.config;
 
 import com.ruoyi.common.exception.CustomException;
 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
 import org.springframework.scheduling.annotation.EnableAsync;
@@ -9,7 +11,7 @@ import org.springframework.security.concurrent.DelegatingSecurityContextExecutor
 
 import java.util.Arrays;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 
 /**
  * 异步配置
@@ -20,13 +22,16 @@ import java.util.concurrent.Executors;
 @Configuration
 public class AsyncConfig extends AsyncConfigurerSupport {
 
+	@Autowired
+	@Qualifier("scheduledExecutorService")
+	private ScheduledExecutorService scheduledExecutorService;
+
     /**
      * 异步执行需要使用权限框架自带的包装线程池  保证权限信息的传递
      */
     @Override
     public Executor getAsyncExecutor() {
-        return new DelegatingSecurityContextExecutorService(
-        	Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));
+        return new DelegatingSecurityContextExecutorService(scheduledExecutorService);
     }
 
     /**

+ 0 - 55
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java

@@ -1,55 +0,0 @@
-package com.ruoyi.framework.manager;
-
-import java.util.TimerTask;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import com.ruoyi.common.utils.Threads;
-import com.ruoyi.common.utils.spring.SpringUtils;
-
-/**
- * 异步任务管理器
- * 
- * @author ruoyi
- */
-public class AsyncManager
-{
-    /**
-     * 操作延迟10毫秒
-     */
-    private final int OPERATE_DELAY_TIME = 10;
-
-    /**
-     * 异步操作任务调度线程池
-     */
-    private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
-
-    /**
-     * 单例模式
-     */
-    private AsyncManager(){}
-
-    private static AsyncManager me = new AsyncManager();
-
-    public static AsyncManager me()
-    {
-        return me;
-    }
-
-    /**
-     * 执行任务
-     * 
-     * @param task 任务
-     */
-    public void execute(TimerTask task)
-    {
-        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
-    }
-
-    /**
-     * 停止任务线程池
-     */
-    public void shutdown()
-    {
-        Threads.shutdownAndAwaitTermination(executor);
-    }
-}

+ 28 - 26
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java

@@ -1,39 +1,41 @@
 package com.ruoyi.framework.manager;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.ruoyi.common.utils.Threads;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
+
 import javax.annotation.PreDestroy;
+import java.util.concurrent.ScheduledExecutorService;
 
 /**
  * 确保应用退出时能关闭后台线程
  *
- * @author ruoyi
+ * @author Lion Li
  */
+@Slf4j(topic = "sys-user")
 @Component
-public class ShutdownManager
-{
-    private static final Logger logger = LoggerFactory.getLogger("sys-user");
+public class ShutdownManager {
+
+	@Autowired
+	@Qualifier("scheduledExecutorService")
+	private ScheduledExecutorService scheduledExecutorService;
 
-    @PreDestroy
-    public void destroy()
-    {
-        shutdownAsyncManager();
-    }
+	@PreDestroy
+	public void destroy() {
+		shutdownAsyncManager();
+	}
 
-    /**
-     * 停止异步执行任务
-     */
-    private void shutdownAsyncManager()
-    {
-        try
-        {
-            logger.info("====关闭后台任务任务线程池====");
-            AsyncManager.me().shutdown();
-        }
-        catch (Exception e)
-        {
-            logger.error(e.getMessage(), e);
-        }
-    }
+	/**
+	 * 停止异步执行任务
+	 */
+	private void shutdownAsyncManager() {
+		try {
+			log.info("====关闭后台任务任务线程池====");
+			Threads.shutdownAndAwaitTermination(scheduledExecutorService);
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		}
+	}
 }

+ 0 - 111
ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java

@@ -1,111 +0,0 @@
-package com.ruoyi.framework.manager.factory;
-
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.AddressUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.system.domain.SysLogininfor;
-import com.ruoyi.system.domain.SysOperLog;
-import com.ruoyi.system.service.ISysLogininforService;
-import com.ruoyi.system.service.ISysOperLogService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.TimerTask;
-
-/**
- * 异步工厂(产生任务用)
- * 
- * @author ruoyi
- */
-public class AsyncFactory
-{
-    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
-
-    /**
-     * 记录登录信息
-     * 
-     * @param username 用户名
-     * @param status 状态
-     * @param message 消息
-     * @param args 列表
-     * @return 任务task
-     */
-    public static TimerTask recordLogininfor(final String username, final String status, final String message,
-            final Object... args)
-    {
-        final UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
-        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                String address = AddressUtils.getRealAddressByIP(ip);
-                StringBuilder s = new StringBuilder();
-                s.append(getBlock(ip));
-                s.append(address);
-                s.append(getBlock(username));
-                s.append(getBlock(status));
-                s.append(getBlock(message));
-                // 打印信息到日志
-                sys_user_logger.info(s.toString(), args);
-                // 获取客户端操作系统
-                String os = userAgent.getOs().getName();
-                // 获取客户端浏览器
-                String browser = userAgent.getBrowser().getName();
-                // 封装对象
-                SysLogininfor logininfor = new SysLogininfor();
-                logininfor.setUserName(username);
-                logininfor.setIpaddr(ip);
-                logininfor.setLoginLocation(address);
-                logininfor.setBrowser(browser);
-                logininfor.setOs(os);
-                logininfor.setMsg(message);
-                // 日志状态
-                if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
-                {
-                    logininfor.setStatus(Constants.SUCCESS);
-                }
-                else if (Constants.LOGIN_FAIL.equals(status))
-                {
-                    logininfor.setStatus(Constants.FAIL);
-                }
-                // 插入数据
-                SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
-            }
-        };
-    }
-
-    /**
-     * 操作日志记录
-     * 
-     * @param operLog 操作日志信息
-     * @return 任务task
-     */
-    public static TimerTask recordOper(final SysOperLog operLog)
-    {
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                // 远程查询操作地点
-                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
-                SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
-            }
-        };
-    }
-
-    public static String getBlock(Object msg)
-    {
-        if (msg == null)
-        {
-            msg = "";
-        }
-        return "[" + msg.toString() + "]";
-    }
-}

+ 26 - 27
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java

@@ -7,8 +7,7 @@ import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
+import com.ruoyi.framework.web.service.AsyncService;
 import com.ruoyi.framework.web.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
@@ -22,33 +21,33 @@ import java.io.IOException;
 
 /**
  * 自定义退出处理类 返回成功
- * 
+ *
  * @author ruoyi
  */
 @Configuration
-public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
-{
-    @Autowired
-    private TokenService tokenService;
+public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
+
+	@Autowired
+	private TokenService tokenService;
+
+	@Autowired
+	private AsyncService asyncService;
+
+	/**
+	 * 退出处理
+	 */
+	@Override
+	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+		throws IOException, ServletException {
+		LoginUser loginUser = tokenService.getLoginUser(request);
+		if (Validator.isNotNull(loginUser)) {
+			String userName = loginUser.getUsername();
+			// 删除用户缓存记录
+			tokenService.delLoginUser(loginUser.getToken());
+			// 记录用户退出日志
+			asyncService.recordLogininfor(userName, Constants.LOGOUT, "退出成功", request);
+		}
+		ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.HTTP_OK, "退出成功")));
+	}
 
-    /**
-     * 退出处理
-     * 
-     * @return
-     */
-    @Override
-    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
-            throws IOException, ServletException
-    {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (Validator.isNotNull(loginUser))
-        {
-            String userName = loginUser.getUsername();
-            // 删除用户缓存记录
-            tokenService.delLoginUser(loginUser.getToken());
-            // 记录用户退出日志
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
-        }
-        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.HTTP_OK, "退出成功")));
-    }
 }

+ 96 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AsyncService.java

@@ -0,0 +1,96 @@
+package com.ruoyi.framework.web.service;
+
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.utils.ServletUtils;
+import com.ruoyi.common.utils.ip.AddressUtils;
+import com.ruoyi.system.domain.SysLogininfor;
+import com.ruoyi.system.domain.SysOperLog;
+import com.ruoyi.system.service.ISysLogininforService;
+import com.ruoyi.system.service.ISysOperLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 异步工厂(产生任务用)
+ *
+ * @author Lion Li
+ */
+@Slf4j(topic = "sys-user")
+@Async
+@Component
+public class AsyncService {
+
+	@Autowired
+	private ISysLogininforService iSysLogininforService;
+
+	@Autowired
+	private ISysOperLogService iSysOperLogService;
+
+	/**
+	 * 记录登录信息
+	 *
+	 * @param username 用户名
+	 * @param status   状态
+	 * @param message  消息
+	 * @param args     列表
+	 */
+	public void recordLogininfor(final String username, final String status, final String message,
+								 HttpServletRequest request, final Object... args) {
+		final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+		final String ip = ServletUtils.getClientIP(request);
+
+		String address = AddressUtils.getRealAddressByIP(ip);
+		StringBuilder s = new StringBuilder();
+		s.append(getBlock(ip));
+		s.append(address);
+		s.append(getBlock(username));
+		s.append(getBlock(status));
+		s.append(getBlock(message));
+		// 打印信息到日志
+		log.info(s.toString(), args);
+		// 获取客户端操作系统
+		String os = userAgent.getOs().getName();
+		// 获取客户端浏览器
+		String browser = userAgent.getBrowser().getName();
+		// 封装对象
+		SysLogininfor logininfor = new SysLogininfor();
+		logininfor.setUserName(username);
+		logininfor.setIpaddr(ip);
+		logininfor.setLoginLocation(address);
+		logininfor.setBrowser(browser);
+		logininfor.setOs(os);
+		logininfor.setMsg(message);
+		// 日志状态
+		if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) {
+			logininfor.setStatus(Constants.SUCCESS);
+		} else if (Constants.LOGIN_FAIL.equals(status)) {
+			logininfor.setStatus(Constants.FAIL);
+		}
+		// 插入数据
+		iSysLogininforService.insertLogininfor(logininfor);
+	}
+
+	/**
+	 * 操作日志记录
+	 *
+	 * @param operLog 操作日志信息
+	 */
+	public void recordOper(final SysOperLog operLog) {
+		// 远程查询操作地点
+		operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
+		iSysOperLogService.insertOperlog(operLog);
+	}
+
+	private String getBlock(Object msg) {
+		if (msg == null) {
+			msg = "";
+		}
+		return "[" + msg.toString() + "]";
+	}
+}

+ 11 - 9
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -11,10 +11,7 @@ import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.framework.config.properties.CaptchaProperties;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
@@ -24,6 +21,7 @@ import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * 登录校验方法
@@ -48,6 +46,9 @@ public class SysLoginService
 	@Autowired
     private ISysUserService userService;
 
+	@Autowired
+	private AsyncService asyncService;
+
     /**
      * 登录验证
      *
@@ -59,16 +60,17 @@ public class SysLoginService
      */
     public String login(String username, String password, String code, String uuid)
     {
+		HttpServletRequest request = ServletUtils.getRequest();
 		if(captchaProperties.getEnabled()) {
 			String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
 			String captcha = redisCache.getCacheObject(verifyKey);
 			redisCache.deleteObject(verifyKey);
 			if (captcha == null) {
-				AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request);
 				throw new CaptchaExpireException();
 			}
 			if (!code.equalsIgnoreCase(captcha)) {
-				AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"), request);
 				throw new CaptchaException();
 			}
 		}
@@ -84,16 +86,16 @@ public class SysLoginService
         {
             if (e instanceof BadCredentialsException)
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"), request);
                 throw new UserPasswordNotMatchException();
             }
             else
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage(), request);
                 throw new CustomException(e.getMessage());
             }
         }
-        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+		asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
         recordLoginInfo(loginUser.getUser());
         // 生成token
@@ -105,7 +107,7 @@ public class SysLoginService
      */
     public void recordLoginInfo(SysUser user)
     {
-        user.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+        user.setLoginIp(ServletUtils.getClientIP());
         user.setLoginDate(DateUtils.getNowDate());
 		user.setUpdateBy(user.getUserName());
         userService.updateUserProfile(user);