Spring Boot集成@Async快速入门Demo

1.什么是@Async?

当我们在使用SpringBoot进行开发的时候,可能会遇到一些执行异步任务的场景,如果每次执行这些异步任务都去新建一个异步线程来执行的话,那代码就太冗余了。幸好SpringBoot给我们提供了Async的注解,让我们能够很轻松地对这些异步任务进行执行。

失效条件

  1. 异步方法使用static修饰
  2. 调用方法和异步方法在同一个类中

2.代码工程

实验目标:验证@async异步任务

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>async</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>

service

  • thenApply : 处理上一阶段计算结果
  • thenCompose: 整合两个计算结果
package com.et.async.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;/*** @author liuhaihua* @version 1.0* @ClassName NotifyServiceimpl* @Description todo*/
@Service
@Slf4j
public class NotifyService {public void noAsync() {log.info("Execute method asynchronously. " + Thread.currentThread().getName());}@Async("threadPoolTaskExecutor")public void withAsync() {log.info("Execute method asynchronously. " + Thread.currentThread().getName());}@Async("threadPoolTaskExecutor")public void mockerror() {int ss=12/0;}@Asyncpublic Future<String> asyncMethodWithReturnType() {log.info("Execute method asynchronously - " + Thread.currentThread().getName());try {Thread.sleep(5000);return new AsyncResult<String>("hello world !!!!");} catch (InterruptedException e) {e.printStackTrace();}return null;}@Autowiredprivate FirstAsyncService fisrtService;@Autowiredprivate SecondAsyncService secondService;public CompletableFuture<String> asyncMergeServicesResponse() throws InterruptedException {CompletableFuture<String> fisrtServiceResponse = fisrtService.asyncGetData();CompletableFuture<String> secondServiceResponse = secondService.asyncGetData();// Merge responses from FirstAsyncService and SecondAsyncServicereturn fisrtServiceResponse.thenCompose(fisrtServiceValue -> secondServiceResponse.thenApply(secondServiceValue -> fisrtServiceValue + secondServiceValue));}
}
package com.et.async.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;/*** @author liuhaihua* @version 1.0* @ClassName FirstAsyncService* @Description todo* @date 2024年05月10日 16:24*/
@Service
@Slf4j
public class FirstAsyncService {@Asyncpublic CompletableFuture<String> asyncGetData() throws InterruptedException {log.info("Execute method asynchronously " + Thread.currentThread().getName());Thread.sleep(4000);return new AsyncResult<>(super.getClass().getSimpleName() + " response !!! ").completable();}
}
package com.et.async.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;import java.util.concurrent.CompletableFuture;/*** @author liuhaihua* @version 1.0* @ClassName SecondAsyncService* @Description todo* @date 2024年05月10日 16:24*/
@Service
@Slf4j
public class SecondAsyncService {@Asyncpublic CompletableFuture<String> asyncGetData() throws InterruptedException {log.info("Execute method asynchronously " + Thread.currentThread().getName());Thread.sleep(4000);return new AsyncResult<>(super.getClass().getSimpleName() + " response !!! ").completable();}
}

config

一个@EnableAsync 注解启用

package com.et.async.config;import com.et.async.exception.CustomAsyncExceptionHandler;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {@Bean(name = "threadPoolTaskExecutor")public Executor threadPoolTaskExecutor() {return new ThreadPoolTaskExecutor();}@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new CustomAsyncExceptionHandler();}
}

异常类

对于无返回值的异步任务,配置CustomAsyncExceptionHandler类,统一处理无法捕获的异常

package com.et.async.exception;import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;import java.lang.reflect.Method;public class CustomAsyncExceptionHandlerimplements AsyncUncaughtExceptionHandler {@Overridepublic void handleUncaughtException(Throwable throwable, Method method, Object... obj) {System.out.println("Exception message - " + throwable.getMessage());System.out.println("Method name - " + method.getName());for (Object param : obj) {System.out.println("Parameter value - " + param);}}}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.

3.测试

测试async异步任务

@Test
public void execute() throws ExecutionException, InterruptedException {log.info("your method test Code");log.info("Invoking an asynchronous method. " + Thread.currentThread().getName());notifyService.noAsync();notifyService.withAsync();}

测试带线程池的异步任务

@Async("threadPoolTaskExecutor")
public void mockerror() {int ss=12/0;
}

测试带返回值的异步方法

@Test
public void testAsyncAnnotationForMethodsWithReturnType()throws InterruptedException, ExecutionException {log.info("Invoking an asynchronous method. " + Thread.currentThread().getName());Future<String> future = notifyService.asyncMethodWithReturnType();while (true) {if (future.isDone()) {log.info("Result from asynchronous process - " + future.get());break;}log.info("Continue doing something else. ");Thread.sleep(1000);}
}

测试多个异步任务合并结果

@Test
public void testAsyncAnnotationForMergedServicesResponse() throws InterruptedException, ExecutionException {log.info("Invoking an asynchronous method. " + Thread.currentThread().getName());CompletableFuture<String> completableFuture = notifyService.asyncMergeServicesResponse();while (true) {if (completableFuture.isDone()) {log.info("Result from asynchronous process - " + completableFuture.get());break;}log.info("Continue doing something else. ");Thread.sleep(1000);}
}

测试void方法异常捕获

@Test
public void mockerror() throws ExecutionException, InterruptedException {notifyService.mockerror();
}

4.引用参考

  • How To Do @Async in Spring | Baeldung
  • Spring Boot集成@Async快速入门Demo | Harries Blog™
  • https://www.cnblogs.com/mingshan/p/17793507.html

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

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

相关文章

【云计算小知识】云管理的作用是什么?

云计算已经成为推动企业数字化转型&#xff0c;提升运营效率的重要力量。而在这个过程中&#xff0c;云管理作为确保云计算环境稳定、高效运行的关键环节&#xff0c;其作用愈发凸显。今天我们小编就给大家详细介绍一下云管理的作用是什么&#xff1f; 云管理的作用是什么&…

小程序的小组件

进度的组件 文字换行过滤 以及 排序 简单易懂 只为了记录工作 <template><div><ProgressBar :progress"progress" /><button click"increaseProgress">增加进度</button><view class"goods-name">12…

【408精华知识】提高外部排序速度的三种方式

文章目录 一、败者树二、置换-选择排序三、最佳归并树 一、败者树 还没写完… 二、置换-选择排序 三、最佳归并树 写在后面 这个专栏主要是我在学习408真题的过程中总结的一些笔记&#xff0c;因为我学的也很一般&#xff0c;如果有错误和不足之处&#xff0c;还望大家在评…

Wikimedia To Opensearch

概览 Wikimedia ⇒ Kafka ⇒ OpensearchJava Library&#xff1a;OKhttp3和OkHttp EventSource&#xff1b;生产者&#xff1a;Wikimedia&#xff1a;WikimediaChangeHandler和WikimediaChangeProducer&#xff1b;消费者&#xff1a;Opensearch&#xff1a;OpenSearchConsume…

AI智能体|我把Kimi接入了个人微信

大家好&#xff0c;我是无界生长。 最近加入AI学习交流群的小伙伴越来越多&#xff0c;我打算在微信群接入一个聊天机器人&#xff0c;让它协助管理微信群&#xff0c;同时也帮忙给群友解答一些问题。普通的群聊机器人肯定是不能满足需求的&#xff0c;得上AI大模型&#xff0c…

Kylin V10SP1桌面版下GBase 8s java udr异常处理

同样的GBase 8s数据库版本&#xff0c;自定义的java udr在Kylin V10SP1 服务器版&#xff08;aarch64架构&#xff09;下创建、运行正常&#xff0c;而在Kylin V10SP1 桌面版&#xff08;aarch64架构&#xff09;下时创建正常但运行UDR异常&#xff0c;报错如下&#xff1a; (…

【JVM类加载机制】深度剖析JVM类加载机制

深度剖析JVM类加载机制 前言类加载运行全过程loadClass的类加载过程 类加载器和双亲委派机制类加载器的类型类加载器的初始化过程双亲委派机制为什么要设置双亲委派机制&#xff1f;全盘负责委托机制自定义类加载器实例打破双亲委派机制Tomcat打破双亲委派机制Tomcat自定义加载…

问题解决记录 | kettle中出现中文乱码

spoon.bat的启动文件中进行修改 if "%PENTAHO_DI_JAVA_OPTIONS%""" set PENTAHO_DI_JAVA_OPTIONS"-Xms1024m" "-Xmx2048m" "-Dfile.encodingUTF-8"

spark结课之小小tip

scala常用方法总结&#xff1a; 1.map()方法&#xff1a;用于对集合中的每个元素应用一个函数&#xff0c;并将结果收集到一个新的集合中。 基本结构&#xff1a; def map[B](f: (A) > B): List[B] 实例&#xff1a; val numbers List(1, 2, 3, 4, 5) val doubledNumber…

废品回收小程序,推动回收行业数字化发展

在垃圾分类、资源回收利用的时代背景下&#xff0c;废品回收行业迅速成长&#xff0c;市场规模逐渐扩大&#xff01; 随着“互联网”应用的普及&#xff0c;废品回收行业也进入到了数字化回收领域&#xff0c;各大回收行业开始专注于发展智能回收。此外&#xff0c;线上废品回…

‘vue-cli-service‘ is not recognized as an internal or external command解决方案

vue-cli-service is not recognized as an internal or external command, operable program or batch file.解决方案 先进行 &#xff1a; npm install -g vue/cli 命令安装vue cli 是必须的。 如果 npm run build 还是报错 遇到同样的提示&#xff1a; 这时候先安装依赖 np…

leetcode56--合并区间

题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;interv…

智慧管家物业管理系统(小组项目)

目录 前言 一、项目介绍 1、目的和背景 2、项目主要内容 3、技术介绍 二、功能模块 1、重要文件结构 2、功能实现&#xff08;部分个人负责模块功能&#xff09; 2.1 展示房源信息页面 2.2 房屋详情页面 2.3 房源信息管理 三、功能模块页面 1、前台模块 2、后台…

【讲解下iCloud如何高效利用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【C语言/数据结构】栈:从概念到两种存储结构的实现

目录 一、栈的概念 二、栈的两种实现方式 1.顺序表实现栈 2.链表实现栈 三、栈的顺序存储结构及其实现 1.栈的声明 2.栈的初始化 3.栈的销毁 4.栈的压栈 5.栈的弹栈 6.栈的判空 7.返回栈顶元素 8.返回栈的长度 四、栈的链式存储结构及其实现 1.栈的声明 2.栈的…

推荐非常方便的初始配置nginx的开源工具

官网 https://www.digitalocean.com/community/tools/nginx?global.app.langzhCN直接复制base64字符串在 /etc/nginx 目录执行&#xff0c;会自动生成配置文件&#xff0c;最后执行 使用tar解压新的压缩配置 tar -xzvf nginxconfig.io-xxx.com.tar.gz | xargs chmod 0644在…

用Transformers实现简单的大模型文本生成

根据输入的prompt&#xff0c;生成一段指定长度的文字。Llama跑起来太慢了&#xff0c;这里用GPT-2作为列子。 from transformers import GPT2LMHeadModel, GPT2Tokenizer import torchtokenizer GPT2Tokenizer.from_pretrained("gpt2") model GPT2LMHeadModel.fr…

打造清洁宜居家园保护自然生态环境,基于YOLOv7【tiny/l/x】参数系列模型开发构建自然生态场景下违规违法垃圾倾倒检测识别系统

自然生态环境&#xff0c;作为我们人类赖以生存的家园&#xff0c;其健康与否直接关系到我们的生活质量。然而&#xff0c;近年来&#xff0c;一些不法分子为了个人私利&#xff0c;在河边、路边等公共区域肆意倾倒垃圾&#xff0c;严重破坏了环境的健康与平衡。这种行为不仅损…

计算机视觉的应用30-基于深度卷积神经网络CNN模型实现物体表面缺陷检测技术的项目

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用30-基于深度卷积神经网络CNN模型实现物体表面缺陷检测技术的项目主要包括&#xff1a;物体表面缺陷检测技术项目介绍&#xff0c;数据构造&#xff0c;模型介绍。 物体表面缺陷检测技术是工业自动化…

[附源码]剑灵三系可乐6.1_Win服务端_联网+单机搭建

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了。 如果你是小白也没…