if (e instanceof BadCredentialsException)
AsyncManager
.me
()
.execute
(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new
UserPasswordNotMatchException
();
AsyncManager
.me
()
.execute
(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new
ServiceException
(e.getMessage());
finally
AuthenticationContextHolder
.clearContext
();
AsyncManager
.me
()
.execute
(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
我们可以看到若依封装了一个异步任务管理器,是以饿汉式的单例模式为全局唯一对象。
调用
execute
方法延迟10s执行任务,需要传入一个
Runnable
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
这里传入的是TimerTask,其实现了Runnable接口
public abstract class TimerTask implements Runnable
A task that can be scheduled for one-time or repeated execution by a Timer.
Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。 TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。
若依使用异步工厂创建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 = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
final String ip = IpUtils.getIpAddr();
return new TimerTask()
@Override
public void run()
String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ip));
s.append(address);
s.append(LogUtils.getBlock(username));
s.append(LogUtils.getBlock(status));
s.append(LogUtils.getBlock(message));
sys_user_logger.info(s.toString(), args);
String os = userAgent.getOperatingSystem().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 (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
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);
若依在aop中记录异常日志也是通过异步任务管理器去创建的
* 拦截异常操作
* @param joinPoint 切点
* @param e 异常
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
handleLog(joinPoint, controllerLog, e, null);
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
LoginUser loginUser = SecurityUtils.getLoginUser();
SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
String ip = IpUtils.getIpAddr();
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
if (loginUser != null)
operLog.setOperName(loginUser.getUsername());
if (e != null)
operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
catch (Exception exp)
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
finally
TIME_THREADLOCAL.remove();
最后在来看一看使用的定时任务线程池
* 执行周期性或定时任务
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService()
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy())
@Override
protected void afterExecute(Runnable r, Throwable t)
super.afterExecute(r, t);
Threads.printException(r, t);
复制代码