文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Boot小型项目如何使用异步任务管理器实现不同业务间的解耦

2022-11-13 14:02

关注

前言

在有些业务场景中,系统对于响应时间有一定的要求,而一个方法里面同步执行的业务逻辑太多势必会影响响应速度,带来不好的用户体验。比如登录时记录登录用户的访问记录、注册时发送邮件、短信通知等等场景,不需要等待处理结果之后再进行下一步操作,这时候就可以使用异步线程进行处理,这样主线程不会因为这些耗时的操作而阻塞,保证主线程的流程可以正常进行。

异步任务可以通过多线程也可以通过消息队列来实现,目的都是为了实现不同业务之间的解耦,提高业务系统的响应速度。但是相对于小型系统采用多线程的方式相对更便捷,所以,这篇文章就记录一下我是如何使用多线程实现异步任务管理器来记录访问日志的。

一、异步任务管理器是什么?

顾名思义,就是用来对异步任务进行统一的管理,并提供了一种访问其唯一对象的方式,这样做的好处就是,在内存中有且仅有一个实例,减少了内存的开销,尤其对于频繁的创建和销毁实例,用这种方式来频繁执行多个异步任务性能是相对比较好的。

二、实现步骤

1.自定义线程池

执行异步任务时,需要将执行的任务放入到线程池中,所以需配置好我们的线程池。并创建一个调度线程池执行器,用来执行异步任务。

代码如下(示例):

2. 新建异步任务管理器类

代码如下(示例):

public class AsyncManager {
    
    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;
    }
    
    public void execute(TimerTask task) {
        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
    }

3. 新建异步工厂类

设计这个类主要是用来产生 TimerTask 的,代码如下(示例):

@Slf4j
public class AsyncFactory {
    
    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. 实现效果

进行登录操作时,会异步进行日志的记录。

总结

到此这篇关于Spring Boot小型项目如何使用异步任务管理器实现不同业务间的解耦的文章就介绍到这了,更多相关Spring Boot实现不同业务间解耦内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯