Spring Boot小型项目如何使用异步任务管理器实现不同业务间的解耦
作者:Java升级之路??????? 发布时间:2022-11-21 07:49:54
前言
在有些业务场景中,系统对于响应时间有一定的要求,而一个方法里面同步执行的业务逻辑太多势必会影响响应速度,带来不好的用户体验。比如登录时记录登录用户的访问记录、注册时发送邮件、短信通知等等场景,不需要等待处理结果之后再进行下一步操作,这时候就可以使用异步线程进行处理,这样主线程不会因为这些耗时的操作而阻塞,保证主线程的流程可以正常进行。
异步任务可以通过多线程也可以通过消息队列来实现,目的都是为了实现不同业务之间的解耦,提高业务系统的响应速度。但是相对于小型系统采用多线程的方式相对更便捷,所以,这篇文章就记录一下我是如何使用多线程实现异步任务管理器来记录访问日志的。
一、异步任务管理器是什么?
顾名思义,就是用来对异步任务进行统一的管理,并提供了一种访问其唯一对象的方式,这样做的好处就是,在内存中有且仅有一个实例,减少了内存的开销,尤其对于频繁的创建和销毁实例,用这种方式来频繁执行多个异步任务性能是相对比较好的。
二、实现步骤
1.自定义线程池
执行异步任务时,需要将执行的任务放入到线程池中,所以需配置好我们的线程池。并创建一个调度线程池执行器,用来执行异步任务。
代码如下(示例):
2. 新建异步任务管理器类
代码如下(示例):
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);
}
3. 新建异步工厂类
设计这个类主要是用来产生 TimerTask 的,代码如下(示例):
@Slf4j
public class AsyncFactory {
/**
* 记录登录信息
* @param username 用户名
* @param status 状态
* @param message 消息
* @param args 列表
* @return 任务task
*/
public static TimerTask recordLoginLog(final String username, final String status, final String message,final Object... args) {
// 客户端操作系统、浏览器等信息
final UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
// 请求的IP地址
final String ip = ServletUtil.getClientIP(ServletUtils.getRequest());
return new TimerTask() {
@Override
public void run() {
String address = AddressUtils.getRealAddressByIp(ip);
// 获取客户端操作系统
String os = userAgent.getOs().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
XlLoginLog loginLog = new XlLoginLog();
loginLog.setUserCode(username);
loginLog.setIpaddr(ip);
loginLog.setLoginLocation(address);
loginLog.setBrowser(browser);
loginLog.setOs(os);
loginLog.setMsg(message);
loginLog.setLoginTime(new Date());
// 日志状态
if (Constants.LOGIN_FAIL.equals(status)) {
loginLog.setStatus(Integer.valueOf(Constants.FAIL));
} else {
loginLog.setStatus(Integer.valueOf(Constants.SUCCESS));
}
// 插入数据
SpringUtils.getBean(IXlLoginLogService.class).create(loginLog);
}
};
}
}
4. 调用
例如:在登录的方法中链式调用,与同步方式不同,开发者不用考虑当进行登录操作是否进行日志操作,在异步的方式中,业务的操作与日志的操作分开来。执行流程:AsyncManager.me()获取一个AsyncManager对象,执行execute方法,执行任务,传入的是一个task对象。实现了Runnable接口,是一个任务,由线程Thread去执行。
recordLoginLog方法返回的是TimerTask定时任务类,将用户登录信息记录到日志中作为一个定时任务,交给定时任务调度线程池scheduledExecutorService,scheduledExecutorService通过在异步任务管理器类中,用getBean()从IOC容器中获取。
5. 实现效果
进行登录操作时,会异步进行日志的记录。
来源:https://juejin.cn/post/7126824958105223199


猜你喜欢
- 安装Free Mybatis plugin即可安装MyBatisCodeHelper插件(推荐)补充:IDEA插件(mybatis框架下ma
- Android UI线程是不安全的,子线程中进行UI操作,可能会导致程序的崩溃,解决办法:创建一个Message对象,然后借助Handler
- 1、实体类package com.yl.bean;import java.io.Serializable;import java.util.
- 将方形的图像映射到正方形上似乎并没有什么难度,所以接下来要做的是把图像映射到球面上。而球的参数方程为x=rcosϕcos&theta
- 简介Springboot Admin是一个管理和监控Springboot项目的组件,分为服务端和客户端,两端通过http进行通信。由于其轻量
- 先要把word或ppt转换为pdf; 以pdf的格式展示,防止文件拷贝。转换方法1、安装Word、Excel、PowerPoint组件注意:
- 何为原子性原子性:一条线程在执行一系列程序指令操作时,该线程不可中断。一旦出现中断,那么就可能会导致程序执行前后的结果不一致。与数据库中的原
- Lambda用到了JDK8自带的一个函数式接口Comparator<T>。准备一个Apple类public class Appl
- 方法1:C#Label1.Text = Request.Form["txtName"].ToString();vb.ne
- 一、引言在移动应用程序的架构设计中,界面与数据即不可分割又不可混淆。在绝大部分的开发经历中,我们都是使用Fragment来进行界面编程,即使
- synchronized关键字,一般称之为”同步锁“,用它来修饰需要同步的方法和需要同步代码块,默认是当前对象作为锁的对象。同步锁锁的是同一
- char类在C#中表示一个unicode字符,正是这些unicode字符构成了字符串。unicode字符是目前计算机中通用的字符编码,它为针
- 这篇文章主要介绍了JAVA基于SnakeYAML实现解析与序列化YAML,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 1.新建文件上传页面在static目录中新建upload-test.html,上传页面代码如下所示:<!DOCTYPE html>
- 简介String是我们最常用的一个类,和普通java类一样其对象会存在java堆中。但是String类有其特殊之处,可以通过new方法生成,
- C# AttributeUsage的使用是如何的呢?首先让我们来了解一下什么是AttributeUsage类它是另外一个预定义特性类,Att
- C#中+=是什么意思在C#中, "+="有两种运用场合。第一种,用在数值后面作为逻辑运算符,自加变量,如:int i=0
- 一、解决的痛点 1、免搭建后端开发环境。 &n
- Java 和 Groovy 中的映射map都是非常通用的,它允许关键字key和值value为任意类型,只要继承了 Object&n
- 本文实例为大家分享了C# TrackBar拖动条改变滑块颜色的具体代码,供大家参考,具体内容如下原理1.TrackBar拖动条的滑块的默认颜