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容器中获取。

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

5. 实现效果

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

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

来源:https://juejin.cn/post/7126824958105223199

标签:Spring,Boot,异步,任务,管理器,不同,业务,解耦
0
投稿

猜你喜欢

  • Spring中IOC和AOP的深入讲解

    2023-11-19 10:20:59
  • java实现微信扫码支付功能

    2023-11-09 18:38:08
  • Java生成压缩文件的实例代码

    2023-02-04 21:11:09
  • C# 键盘Enter键取代Tab键实现代码

    2022-11-21 08:53:14
  • Spring Boot整合流控组件Sentinel的场景分析

    2023-06-22 19:27:53
  • 详解Maven安装教程及是否安装成功

    2021-07-14 00:00:21
  • java中匿名内部类详解

    2022-10-06 14:56:56
  • 如何用Java注解和反射实现依赖注入

    2022-11-04 11:34:10
  • Java Object类中的常用API介绍

    2023-11-09 01:51:00
  • SpringBoot持久化层操作支持技巧

    2023-11-24 06:40:32
  • android studio编译jar包或者aar包的方法教程详解

    2023-06-18 17:22:32
  • java IO流 之 输入流 InputString()的使用

    2023-08-22 07:44:31
  • Java正则验证正整数的方法分析【测试可用】

    2022-08-02 21:50:05
  • 详解 Corba开发之Java实现Service与Client

    2023-09-23 03:42:48
  • java处理数据库不支持的emoji表情符问题解决

    2021-08-21 00:16:58
  • Java网络编程之简易聊天室的实现

    2022-05-05 22:23:45
  • SpringBoot之Helloword 快速搭建一个web项目(图文)

    2023-08-23 17:36:21
  • spring异步service中处理线程数限制详解

    2021-09-02 23:20:12
  • Java编程BigDecimal用法实例分享

    2022-05-02 05:40:06
  • SpringBoot整合SpringTask实现定时任务的流程

    2022-03-28 22:24:40
  • asp之家 软件编程 m.aspxhome.com