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

springboot中异步接口实现所有方式_20250501

几种异步接口实现demo

package org.dromara.controller.app;// 导入必要的依赖库import cn.dev33.satoken.annotation.SaIgnore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.WebAsyncTask;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Map;
import java.util.concurrent.*;/*** 异步接口实现方式大全* 演示Spring Boot中多种异步处理方案:* 1. 响应体发射器(ResponseBodyEmitter)* 2. 服务器发送事件(SSE)* 3. 文件流传输* 4. Callable异步调用* 5. WebAsyncTask* 6. 延迟结果(DeferredResult)*/
@Slf4j // Lombok生成日志对象
@SaIgnore // 忽略权限校验
@RestController // REST控制器
@RequestMapping("testAsync") // 请求路径前缀
public class TestAsyncController {// 创建单线程定时任务线程池private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);// 延迟结果存储容器(线程安全)private static final Map<String, DeferredResult<String>> DEFERRED_RESULT_MAP = new ConcurrentHashMap<>();/*** 使用ResponseBodyEmitter实现持续通信* 每2秒向客户端发送时间戳消息*/@GetMapping("/emitter")public ResponseEntity<ResponseBodyEmitter> handle() {// 创建响应发射器ResponseBodyEmitter emitter = new ResponseBodyEmitter();// 定时任务:每2秒发送一次消息scheduler.scheduleAtFixedRate(() -> {try {emitter.send(String.format("timestamp: %d\n", System.currentTimeMillis()), MediaType.TEXT_PLAIN);} catch (IOException e) {throw new RuntimeException(e);}}, 0, 2, TimeUnit.SECONDS); // 初始延迟0s,间隔2s// 设置10秒超时处理// 关闭连接emitter.onTimeout(emitter::complete);return new ResponseEntity<>(emitter, HttpStatus.OK);}/*** 使用SseEmitter实现服务器发送事件(SSE)* 每3秒推送自定义事件消息*/@GetMapping("/sse")public SseEmitter handleSse() {SseEmitter emitter = new SseEmitter();// 定时事件推送(3秒间隔)scheduler.scheduleAtFixedRate(() -> {try {// 构建SSE事件:事件名+数据SseEmitter.SseEventBuilder event = SseEmitter.event().name("sse").data(String.format("timestamp: %d", System.currentTimeMillis()));emitter.send(event);} catch (IOException e) {emitter.completeWithError(e); // 发生异常时关闭连接}}, 0, 3, TimeUnit.SECONDS);// 15秒超时处理// 关闭连接emitter.onTimeout(emitter::complete);return emitter;}/*** 文件流式传输示例* 实现大文件下载(模拟)*/@GetMapping("/stream")public ResponseEntity<StreamingResponseBody> handleStream() throws MalformedURLException {// 创建远程资源对象(演示用URL)Resource resource = new UrlResource("https://blog.csdn.net/lcj_star/");// 流式响应体实现StreamingResponseBody stream = outputStream -> {try (InputStream inputStream = resource.getInputStream()) {byte[] buffer = new byte[1024];int bytesRead;// 分块传输文件内容while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}} catch (IOException e) {log.error("文件读取失败: {}", e.getMessage(), e);}};// 构建响应头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 二进制流类型headers.setContentDispositionFormData("attachment", resource.getFilename()); // 强制下载return ResponseEntity.ok().headers(headers).body(stream);}/*** Callable异步处理示例* 模拟耗时操作后返回结果*/@GetMapping("/callAble")public Callable<String> testCallAble() {return () -> {Thread.sleep(4000); // 模拟4秒耗时return "hello"; // 返回结果};}/*** WebAsyncTask异步处理示例* 支持超时和完成回调*/@GetMapping("/webAsyncTask")public WebAsyncTask<String> webAsyncTask() {// 创建异步任务(超时时间30003ms)WebAsyncTask<String> result = new WebAsyncTask<>(30003, () -> {return "success"; // 任务主体});// 超时回调result.onTimeout(() -> {log.info("timeout callback");return "timeout callback";});// 完成回调result.onCompletion(() -> log.info("finish callback"));return result;}/*** 延迟结果示例* 持有连接等待外部触发结果*/@GetMapping("/deferredResult")public DeferredResult<String> testDeferredResult() {DeferredResult<String> deferredResult = new DeferredResult<>();DEFERRED_RESULT_MAP.put("demo", deferredResult); // 存储实例return deferredResult; // 挂起请求}/*** 触发延迟结果* 外部调用设置结果*/@GetMapping("/setDeferredResult")public String testSetDeferredResult() {DeferredResult<String> deferredResult = DEFERRED_RESULT_MAP.get("demo"); // 获取实例boolean flag = deferredResult.setResult("DeferredResult hello"); // 设置结果if (!flag) {log.info("结果已经被处理,此次操作无效");}return "success";}
}

总结

技术适用场景特点
ResponseBodyEmitter持续文本流传输手动控制发送时机
SseEmitter服务端事件推送SSE协议支持
StreamingResponseBody文件流传输适用于大文件下载
Callable简单异步处理自动包装异步执行
WebAsyncTask需回调控制支持超时/完成回调
DeferredResult外部触发可跨请求设置结果
http://www.xdnf.cn/news/3383.html

相关文章:

  • 内存 “舞台” 上,进程如何 “翩翩起舞”?(转)
  • idea安装
  • 【Unity】 组件库分类详解
  • RAGFlow报错:ESConnection.sql got exception
  • 【基础算法】插值查找算法 - JAVA
  • (即插即用模块-Attention部分) 六十一、(2024 ACCV) LIA 基于局部重要性的注意力
  • 【数据分享】2020年中国高精度森林覆盖数据集(免费获取)
  • VBA数据库解决方案第二十讲:Select From Where条件表达式
  • 「面白い」日本 课文详解
  • 【MySQL数据库】视图
  • Flutter PIP 插件 ---- 新增PipActivity,Android 11以下支持自动进入PIP Mode
  • ARM ASM
  • 【云原生】基于Centos7 搭建Redis 6.2 操作实战详解
  • 【五一培训】Day1
  • Redis 挂掉后高并发系统的应对策略:使用 Sentinel 实现限流降级与 SkyWalking 监控优化
  • PostgreSQL 数据库下载和安装
  • Stm32 烧录 Micropython
  • 基于机器学习的舆情分析算法研究
  • 连接linux虚拟机并运行C++【从0开始】
  • 机器学习实战,天猫双十一销量与中国人寿保费预测,使用多项式回归,梯度下降,EDA数据探索,弹性网络等技术
  • vue中$set原理
  • Meta公司于2025年4月29日正式推出了全新Meta AI应用程序的首个版本
  • 正则表达式:精准匹配,高效处理文本
  • 《软件设计师》复习笔记(11.1)——生命周期、CMM、开发模型
  • 结构模式识别理论与方法
  • JWT Access Token 被窃取的风险与解决方案
  • spring-boot-maven-plugin 将spring打包成单个jar的工作原理
  • 企业经营系统分类及功能详解
  • 华为eNSP:IS-IS认证
  • 机器人--主机--控制系统