当前位置: 首页 > news >正文

Spring开发实践(二)

@EnableAsync@Async 注解的使用方法

@EnableAsync@Async 是Spring框架中的两个注解,用于启用和使用异步方法执行。它们可以帮助你在Spring应用程序中实现异步编程,从而提高应用程序的性能和响应速度。

@EnableAsync

@EnableAsync 注解用于启用Spring的异步方法执行功能。你需要在配置类或主应用程序类上添加这个注解,以便Spring能够扫描并处理 @Async 注解的方法。

@Async

@Async 注解用于标记一个方法为异步方法。当Spring调用这个方法时,它会在一个独立的线程中执行,而不会阻塞调用者的线程。

使用步骤

  1. 启用异步支持:在配置类或主应用程序类上添加 @EnableAsync 注解。
  2. 标记异步方法:在需要异步执行的方法上添加 @Async 注解。

示例代码

1. 启用异步支持

在主应用程序类或配置类上添加 @EnableAsync 注解。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@EnableAsync
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
2. 标记异步方法

在需要异步执行的方法上添加 @Async 注解。

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class MyService {@Asyncpublic void performAsyncTask() {// 这个方法将在一个独立的线程中执行System.out.println("执行异步任务");try {Thread.sleep(5000); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步任务完成");}
}
3. 调用异步方法

在其他地方调用异步方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/async")public String executeAsyncTask() {myService.performAsyncTask();return "异步任务已提交";}
}

注意事项

  1. 返回类型:异步方法可以返回 voidFutureCompletableFuture。如果需要获取异步方法的结果,可以使用 FutureCompletableFuture
@Async
public CompletableFuture<String> performAsyncTaskWithResult() {// 这个方法将在一个独立的线程中执行System.out.println("执行异步任务");try {Thread.sleep(5000); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.completedFuture("异步任务完成");
}
  1. 线程池配置:默认情况下,Spring使用一个简单的线程池来执行异步任务。你可以自定义线程池,以满足特定的性能需求。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;@Configuration
@EnableAsync
public class AsyncConfig {@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}
  1. 类级别的 @Async:你也可以在类级别上使用 @Async 注解,表示该类中的所有方法都将异步执行。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
@Async
public class MyService {public void performAsyncTask() {// 这个方法将在一个独立的线程中执行System.out.println("执行异步任务");}
}

通过使用 @EnableAsync@Async 注解,你可以轻松地在Spring应用程序中实现异步方法执行,从而提高应用程序的性能和响应速度。

获取异步结果

主线程可以通过 CompletableFuture 的方法来获取异步任务的结果。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/async")public String executeAsyncTask() throws ExecutionException, InterruptedException {// 调用异步方法,立即返回一个 CompletableFuture 对象CompletableFuture<String> future = myService.performAsyncTaskWithResult();// 主线程不会被阻塞,可以继续执行其他操作System.out.println("异步任务已提交");// 获取异步任务的结果(会阻塞直到结果可用)String result = future.get();return result;}
}

总结

  • 调用异步方法时:由于 @Async 注解,异步方法将在一个独立的线程中执行,调用该方法的主线程不会被阻塞。
  • 立即返回 CompletableFuture 对象:调用异步方法后,主线程会立即返回一个 CompletableFuture 对象,表示异步任务的结果。
  • 获取结果:主线程可以通过 CompletableFuture 的方法来获取异步任务的结果,而不需要等待异步任务完成。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深度学习-梯度下降算法-NLP(五)
  • Ubuntu24.04清理常见跟踪软件tracker
  • Unity Addressable魔改
  • Android 列表视频滑动自动播放—滑动过程自动播放(实现思路)
  • tableau范围-线图与倾斜图绘制 - 14
  • CSS 中的 ::before 和 ::after 伪元素
  • 同三维T80006EH2-4K30编码器视频使用操作说明书:高清HDMI编码器,高清SDI编码器,4K超清HDMI编码器,双路4K超高清编码器
  • vue3项目中浏览器打开本地文档或者下载本地应用的方法(2024-07-11)
  • clean code-代码整洁之道 阅读笔记(第十七章 终章)
  • 【排序 - 快速排序】
  • 大模型/NLP/算法面试题总结9——从普通注意力换成多头注意力会导致参数暴涨吗?
  • 渔人杯——RE
  • git批量删除本地包含某字符串的特定分支
  • 04.ffmpeg打印音视频媒体信息
  • linux从入门到精通
  • python3.6+scrapy+mysql 爬虫实战
  • __proto__ 和 prototype的关系
  • C++入门教程(10):for 语句
  • codis proxy处理流程
  • crontab执行失败的多种原因
  • Docker 笔记(2):Dockerfile
  • java2019面试题北京
  • Java多态
  • Java多线程(4):使用线程池执行定时任务
  • js中的正则表达式入门
  • Laravel 中的一个后期静态绑定
  • Spring Boot MyBatis配置多种数据库
  • Vue 重置组件到初始状态
  • Vue2 SSR 的优化之旅
  • Web设计流程优化:网页效果图设计新思路
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 移动端 h5开发相关内容总结(三)
  • 怎样选择前端框架
  • MPAndroidChart 教程:Y轴 YAxis
  • PostgreSQL之连接数修改
  • Python 之网络式编程
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​zookeeper集群配置与启动
  • # Apache SeaTunnel 究竟是什么?
  • #ifdef 的技巧用法
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (55)MOS管专题--->(10)MOS管的封装
  • (备份) esp32 GPIO
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (十) 初识 Docker file
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (数据结构)顺序表的定义
  • (一)RocketMQ初步认识
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?