Spring Boot | Spring Boot 整合 “异步任务“ 的实现

目录:

    • 一、异步任务
      • 1.1 "无返回值" 异步任务调用 :
        • ① 创建项目
        • ② 编写 "异步调用方法" ( 使用 @Async 注解 )
        • ③ "主程序启动类"中 开启基于 "注解" 的异步任务支持 ( 使用@EnableAsync注解 )
        • ④ 编写 "控制层" 相关方法
        • ⑤ "异步任务" 效果测试
      • 1.2 "有返回值" 异步任务调用 :
        • ① 创建项目
        • ② 编写 "异步调用方法" ( 使用 @Async 注解 )
        • ③ "主程序启动类"中 开启基于 "注解" 的异步任务支持 ( 使用@EnableAsync注解 )
        • ④ 编写 "控制层" 相关方法
        • ⑤ "异步任务" 效果测试

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


  • 开发 Web 应用时,多数应用具备 “任务调度” 功能。( Spring Boot 任务管理 ) 常见的任务 包括 ① 异步任务
    ② 定时任务③ 发"邮件任务"
  • 我们将以数据库报表为例看看任务调度如何 帮助改善 “系统设计”报表可能是错综复杂的,用户可能需要很长时间找到需要的报表数据,此时,我们可以在这个报表应用添加"异步任务"减少用户等待时间,从而 提高用户体验
  • 除此之外,还可以在 报表应用添加"定时任务" 和 "邮件任务" ,以便用户可以安排在任何他们 需要的时间 "定时"生成报表,并在 Email发送。下面将介绍如何使用Spring Boot开发这些常见的任务

一、异步任务

  • Web 应用开发中,大多数情况都是通过 同步方式 完成数据交互处理,但是,处理与第三方系统的交互容易造成 响应迟缓的情况,之前大部分都是使用 “多线程完成此类任务,除此之外,还可以使用 异步调用 的方式完美解决这个问题
  • 根据 异步处理方式的不同,可以将 异步任务的调用分为 无返回值异步任务调用 有返回值异步任务 调用。

1.1 “无返回值” 异步任务调用 :

  • 实际开发中,项目 可能会 向新注册用户 "发送短信验证码",这时,可以考虑使用 异步任务调用的方式实现一方面是因为用户对这个时效性要求 不是特别高 ( 实际发送验证码客户手机上是要1-几秒的时间的 ,但提示说"验证码"已发送 这个可是几乎马上响应的,这两个动作有时间差前者满后者快,就是因为使用了 “异步任务” , 让"慢的动作" 和 “快的动作区分开来 ,这个效果是用"异步任务实现的" ,) 。
    一方面特定时间范围内没有收到验证码用户可以点击再次发送验证码。下面将使用Spring Boot框架演示这种场景需求,进一步说明 无返回值的异步任务调用

    ps
    实际情况时,点了获得验证码之后,系统快速回应说验证码已发送 ( 假设其是"主程序" ),然后 验证码过了一段时间才实际发到手机上 ( 假设其是 “次程序” )的,这两个动作是有 时间差的,怎么实现这个效果? 或者说 不用这种效果会有什么缺点呢?—在次程序这里使用了 “异步任务

    如果不使用 "异步任务" , 那么此时的i效果 就是 : 点了"发送验证码"按钮后要等几秒之后才说"验证码已发送",然后 “实际的” 验证码也发送到手机上,此时两个动作是没什么时间差的,这种效果好吗?
    ---- 那肯定是不好的,因为验证码过一段时间才发送到手机上的, 那为什么要让"主程序"也陪着一起等几秒呢? ,所以用了"异步任务"之后,主程序就可以快速做出响应,然后"次程序"执行多久就多久,客户只需等待就好。

① 创建项目
  • 创建项目 :

    在这里插入图片描述

    需要说明的是Spring 框架 提供了对 异步任务支持SpringBoot框架继承了这一 异步任务 功能。在 Spring Boot 中整合异步任务时,只需在项目中引入Web 模块中的 Web 依赖就可以使用这种异步任务功能。

② 编写 “异步调用方法” ( 使用 @Async 注解 )
  • 在项目中创建 service包,并在该包下创建一个业务实现类 : MyAsyncService,在该类中编写模拟用户短信验证码发送方法例子代码如下 :

    MyAsyncService.java

    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;@Service //加入IOC容器
    public class MyAsyncService { //"异步任务" 业务类@Async //标记该方法为"异步方法" (此时该异步方法还不会生效,要在主程序启动类中添加 @EnableAsync注解 )//该方法用于模拟"发送短信验证码"public void sendSms() throws Exception{System.out.println("--------------------");System.out.println("调用短信验证码业务方法...,验证码发送中,请稍等...");/*System.currentTimeMillis():返回当前时间与1970年1月1日00:00:00 GMT之间的 "毫秒数"。这个方法通常用于生成"时间戳",它可以帮助我们跟踪和记录事件发生的时间。*/Long startTime = System.currentTimeMillis();Thread.sleep(5000); //线程"睡眠"5秒Long endTime = System.currentTimeMillis();System.out.println("验证码真正实际发送到手机中~");System.out.println("短信业务执行完成耗时:(次流程) "+(endTime-startTime));}}
    
③ "主程序启动类"中 开启基于 “注解” 的异步任务支持 ( 使用@EnableAsync注解 )
  • 上一步编写的 用户短信验证码发送业务方法中,使用 @Async 注解标记了异步方法如果想要异步方法生效,还需要使用 @EnableAsync 注解 开启基于注解异步任务支持 ( 让被 “@Async注解” 标记的"异步方法"生效 )。@EnableAsync 注解通常会添加在 项目启动类 上,例子代码如下

    Chapter25Application.java ( 主程序启动类 ):

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableAsync;@EnableAsync //开启基于"注解"的异步任务支持 ( 让被 "@Async注解" 标记的"异步方法"生效 )
    @SpringBootApplication
    public class Chapter25Application {public static void main(String[] args) {SpringApplication.run(Chapter25Application.class, args);}
    }
    
④ 编写 “控制层” 相关方法
  • 在项目中创建 controller,在该包下创建类 MyAsyncControler用于 调用异步方法。在该类中模拟编写用户短信验证码发送处理方法,例子代码如下 :

    MyAsyncService.java :

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;@ResponseBody //将方法的返回值转换为“指定类型”且存入到响应体中
    @Controller //将该类加入到IOC容器中
    public class MyAsyncController {// "控制层"相关内容@Autowiredprivate MyAsyncService myAsyncService;@GetMapping("/sendSMS")public String sendSms() throws Exception {long startTime = System.currentTimeMillis();//调用"业务层"中的"发送短信方法"myAsyncService.sendSms();long endTime = System.currentTimeMillis();System.out.println("验证码已发送...( 客户得到提示:验证码已发送~ )");System.out.println("主流程耗时: "+(endTime-startTime));return "success"; //响应该字符串信息给前端}
    }
    
⑤ “异步任务” 效果测试
  • 启动项目后,在浏览器上访问 http://localhost:8080/sendSMS ,测试"异步任务"请求,此时**控制台打印信息** 如下图所示 :

    在这里插入图片描述


    在这里插入图片描述

    演示结果可以看出,执行 sendSMS( )方法并调用异步方法处理短信业务时,在 很短的时间内(1毫秒)完成了主流程的执行,并向页面响应主流程结果,而在主流程打印输出方法之前 调用的 异步方法 经过一段时间后才执行完毕 ( 主次流程之间存在"时间差" ,此时为了不影响用户体验,可用 “异步任务” ) 。因此,从执行结果可以发现,案例中无返回值异步任务调用成功

    需要说明 的是,上述案例中的异步方法没有返回值 的,这样 主流程执行异步方法不会阻塞,而是继续向下执行主流程程序,直接向页面响应结果,而调用异步方法会作为 一个子线程单独执行,直到 异步方法执行完成

  • 注释 @Async注解重启动项目访问路径,看看""异步任务 和 ""异步任务区别 :

    在这里插入图片描述


    在这里插入图片描述

1.2 “有返回值” 异步任务调用 :

  • 实际开发中,项目中可能会涉及 有返回值异步任务调用。例如,一个程序中需要 调用两个业务方法 对相关 业务数据统计分析,并将统计结果汇总。下面j将使用 Spring Boot框架演示这种场景需求,进一步说明 有返回值异步任务 调用。
① 创建项目
  • 创建项目 :

    在这里插入图片描述

    需要说明的是Spring 框架 提供了对 异步任务支持SpringBoot框架继承了这一 异步任务 功能。在 Spring Boot 中整合异步任务时,只需在项目中引入Web 模块中的 Web 依赖就可以使用这种异步任务功能。

② 编写 “异步调用方法” ( 使用 @Async 注解 )
  • 在项目中创建 service包,并在该包下创建一个业务实现类 : MyAsyncService,在该类中编写 两个模拟有返回值异步任务业务处理方法
    例子代码如下 :

    MyAsyncService.java

    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.stereotype.Service;import java.util.concurrent.Future;@Service //加入IOC容器
    public class MyAsyncService { //"异步任务" 业务类@Asyncpublic Future<Integer> processA() throws Exception{ //该"异步方法"有一定的"处理时间",并且返回统计结果。System.out.println("开始分析统计业务A数据.....");Long startTime = System.currentTimeMillis();//休眠Thread.sleep(4000); //线程"睡眠"5秒//模拟定义一个假的统计结果int count = 123456;Long endTime = System.currentTimeMillis();System.out.println("业务A数据统计耗时: "+(endTime-startTime));//使用AsyncResult对象封装 返回的"异步结果数据",该方法的返回值为 Future类型return new AsyncResult<Integer>(count);}@Asyncpublic Future<Integer> processB() throws Exception{ //该"异步方法"有一定的"处理时间",并且返回统计结果。System.out.println("开始分析统计业务B数据.....");Long startTime = System.currentTimeMillis();//休眠Thread.sleep(5000); //线程"睡眠"5秒//模拟定义一个假的统计结果int count = 654321;Long endTime = System.currentTimeMillis();System.out.println("业务B数据统计耗时: "+(endTime-startTime));//使用AsyncResult对象封装 返回的"异步结果数据",该方法的返回值为 Future类型return new AsyncResult<Integer>(count);}}
③ "主程序启动类"中 开启基于 “注解” 的异步任务支持 ( 使用@EnableAsync注解 )
  • 上一步编写的 用户短信验证码发送业务方法中,使用 @Async 注解标记了异步方法如果想要异步方法生效,还需要使用 @EnableAsync 注解 开启基于注解异步任务支持 ( 让被 “@Async注解” 标记的"异步方法"生效 )。@EnableAsync 注解通常会添加在 项目启动类 上,例子代码如下

    Chapter25Application.java ( 主程序启动类 ):

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableAsync;@EnableAsync //开启基于"注解"的异步任务支持 ( 让被 "@Async注解" 标记的"异步方法"生效 )
    @SpringBootApplication
    public class Chapter25Application {public static void main(String[] args) {SpringApplication.run(Chapter25Application.class, args);}
    }
    
④ 编写 “控制层” 相关方法
  • 编写 "控制层" 相关方法

    MyAsyncController.java

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;import java.util.concurrent.Future;@ResponseBody //将方法的返回值转换为“指定类型”且存入到响应体中 --让return 字符串时,不被默认识别为一个"视图页面"
    @Controller //将该类加入到IOC容器中
    public class MyAsyncController {// "控制层"相关内容@Autowiredprivate MyAsyncService myAsyncService;@GetMapping("/statistics")public String statistics() throws Exception {long startTime = System.currentTimeMillis();//"有返回值"的 "异步任务"Future<Integer> futureA = myAsyncService.processA();Future<Integer> futureB = myAsyncService.processB();int total = futureA.get()+futureB.get();System.out.println("异步任务数据统计汇总结果: "+total);long endtTime = System.currentTimeMillis();System.out.println("主流程耗时: "+(endtTime-startTime));return "success"; //响应该字符串信息给前端}}
    
⑤ “异步任务” 效果测试
  • 启动项目后,在浏览器上访问 http://localhost:8080/statistics ,测试"异步任务"请求,此时 控制台打印信息下图所示 :

    在这里插入图片描述

    演示结果可以看出,执行 statistics( )方法调用异步方法处理业务数据统计时,需要 耗费一定的时间(5004毫秒)完成主流程的执行,并向页面响应结果,而在主流程打印输出结果之前一直等待着业务A 和业务 B 两个异步方法异步调用处理结果汇总。因此,从执行结果可以发现,案例中 有返回值异步任务调用成功


需要说明的是,上述的异步方法有返回值的,当返回值较多时 主流程执行异步方法是会有 短暂阻塞需要等待并获取异步方法的 返回结果,而调用的两个异步方法会作为两个子线程 “并行执行”,直到异步方法执行完成返回结果,这样 主流程 会在 最后一个异步方法返回结果后跳出阻塞状态

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/9484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0到1构建AI agent【零代码】

一、前言 想象一下&#xff0c;如果AI的想象力被彻底释放&#xff0c;那将是一场怎样的革命&#xff1f;“大语言模型不过是个贪吃蛇&#xff0c;而AI Agent却能创造出‘王者荣耀’。”这不仅是网上的一句戏言&#xff0c;它预示着一个不可逆转的趋势。比尔盖茨更是一语中的&am…

【全开源】Java共享台信息共享系统源码

特色功能 信息整合与共享&#xff1a;该平台提供一站式信息整合服务&#xff0c;将各种类型的信息资源进行汇聚&#xff0c;方便用户快速查找和获取所需资源。多种共享功能&#xff1a;支持信息共享、共享车位、共享会议室、共享电动车等多种共享功能&#xff0c;提高资源利用…

【Linux】18. 进程间通信 --- System V IPC(选学)

System V IPC System V 消息队列System V 共享内存System V 信号量 system V 共享内存 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核。 换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据…

云南区块链商户平台优化开发

背景 云南区块链商户平台是全省统一区块链服务平台。依托于云南省发改委、阿里云及蚂蚁区块链的国内首个省级区块链平台——云南省区块链平台同步上线&#xff0c;助力数字云南整体升级。 网页版并不适合妈妈那辈人使用&#xff0c;没有记忆功能&#xff0c;于是打算自己开发…

k8s介绍

一、前言 Kubernetes&#xff08;通常简称为 K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序&#xff0c;它提供了丰富的功能使得用户能够轻松地管理大规模的容器集群&#xff0c;包括自动化部署和扩展、服务发现和负载均衡、存…

漫威争锋Marvel Rivals怎么搜索 锁区怎么搜 游戏搜不到怎么办

即将问世的《漫威争锋》&#xff08;Marvel Rivals&#xff09;作为一款万众期待的PvP射击游戏新星&#xff0c;荣耀携手漫威官方网站共同推出。定档5月11日清晨9时&#xff0c;封闭Alpha测试阶段将正式揭开序幕&#xff0c;持续时间长达十天之久。在此首轮测试窗口&#xff0c…

一个开源即时通讯源码

一个开源即时通讯源码 目前已经含服务端、PC、移动端即时通讯解决方案&#xff0c;主要包含以下内容。 服务端简介 不要被客户端迷惑了&#xff0c;真正值钱的是服务端&#xff0c; 服务是采用Java语言开发&#xff0c;基于spring cloud微服务体系开发的一套即时通讯服务端。…

栈结构(c语言)

1.栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&am…

STM32的ADC详解

ADC即模拟数字转换器&#xff0c;通常用于将外部的模拟量信号转换为数字信号。STM32的ADC是12位逐次逼近型的模拟数字转换器&#xff0c;最大可以计数到4095&#xff0c;有18个通道&#xff0c;16个外部通道和2个内部通道。 ADC框图 ADC的功能框图可以分为七个部分&#xff1a…

记一次springboot jpa更新复杂几何类型报错Only simple geometries should be used

问题&#xff1a; 更新数据时&#xff0c; 几何字段MultiPolygon类型时报错&#xff1b; java.lang.IllegalStateException: Only simple geometries should be used 几何字段Point类型时不报错&#xff1b; 新增时字段存在MultiPolygon不报错。 查看日志可知&#xff0c;…

vscode 使用正则搜索

ctrl c 复制&#xff0c;内容如下&#xff1a; Vue3简介创建Vue3工程Vue3核心语法路由pinia组件通信其它 APIVue3新组件

Go 单元测试完全指南(一)- 基本测试流程

为什么写单元测试&#xff1f; 关于测试&#xff0c;有一张很经典的图&#xff0c;如下&#xff1a; 说明&#xff1a; 测试类型成本速度频率E2E 测试高慢低集成测试中中中单元测试低快高 也就是说&#xff0c;单元测试是最快、最便宜的测试方式。这不难理解&#xff0c;单元…

Baidu Comate:让编码实现无限可能

目录 1 背景介绍2 快速入门2.1 智能推荐功能2.2 智能生成功能2.2.1 智能注释2.2.2 智能生成2.2.3 智能调优2.2.4 代码解释 3 高兼容性4 即刻体验 1 背景介绍 Baidu Comate&#xff08;智能代码助手&#xff09;是基于文心大模型&#xff0c;结合百度积累多年的编程现场大数据和…

【MySQL数据库】丨一文详解 JdbcTemplate(Spring中的CRUD)

前言 JdbcTemplate 是 Spring框架 中提供的一个对象&#xff0c;用于简化JDBC操作。它使得数据库操作变得更为简单和方便&#xff0c;大大提高了开发效率。 文章目录 前言为何要使用JdbcTemplate在JdbcTemplate中执行SQL语句的方法大致分为3类&#xff1a;案例代码 JdbcTemplat…

word 毕业论文格式调整

添加页眉页脚 页眉 首先在页面上端页眉区域双击&#xff0c;即可出现“页眉和页脚”设置页面&#xff1a; 页眉左右两端对齐 如果想要页眉页脚左右两端对齐&#xff0c;可以选择添加三栏页眉&#xff0c;然后将中间那一栏删除&#xff0c;即可自动实现左右两端对齐&#x…

Linux 操作系统TCP、UDP

1、TCP服务器编写流程 头文件&#xff1a; #include <sys/socket.h> 1.1 创建套接字 函数原型&#xff1a; int socket(int domain, int type, int protocol); 参数&#xff1a; domain: 网域 AF_INET &#xff1a; IPv4 AF_INET6 &a…

fswatch工具:跟踪Linux中的文件和目录更改

fswatch是一个跨平台的文件更改监视器&#xff0c;当指定文件或目录的内容被更改或修改时&#xff0c;它会收到通知警报。 fswatch在不同的操作系统上执行多种类型的监视器&#xff0c;例如&#xff1a; 基于 Apple OS X 的文件系统事件 API 构建的监视器。基于kqueue的监视器…

WPF之DataGird应用

1&#xff0c;DataGrid相关属性 GridLinesVisibility&#xff1a;DataGrid网格线是否显示或者显示的方式。HorizontalGridLinesBrush&#xff1a;水平网格线画刷。VerticalGridLinesBrush&#xff1a;垂直网格线画刷。HorizontalScrollBarVisibility&#xff1a;水平滚动条可见…

ASP.NET MVC 如何使用 Form Authentication?

前言 .NET 的 Form Authentication 是一种基于表单的简单且灵活的身份验证机制&#xff0c;用户通过输入用户名和密码来登录应用程序&#xff0c;并且通过配置来控制用户访问权限。 在使用 Form Authentication 时&#xff0c;我们需要在 web.config 文件中配置身份验证和授权…

Spring Cloud Consul 4.1.1

该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法&#xff0c;为 Spring Boot 应用程序提供 Consul 集成。通过一些简单的注释&#xff0c;您可以快速启用和配置应用程序内的常见模式&#xff0c;并使用基于 Consul 的组件构建大型分布式系统。提供的模式…