You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Spring WebFlux设计非阻塞REST控制器及异步链式调用?

WebFlux中串联异步调用并返回结果的正确实现

当前问题分析

直接调用credentialMono.subscribe(credential -> callApi(credential))是错误的,原因如下:

  • subscribe是触发异步执行的操作,但它不会将后续API调用的结果整合到返回给控制器的Mono中。
  • 控制器拿到的Mono会立即完成,不会等待API调用的结果,导致客户端无法获取到正确的响应。

正确实现方式

WebFlux的核心是通过响应式操作符构建链式调用,这里需要使用flatMap操作符,它可以将一个Mono<T>转换为另一个Mono<R>,完美适配你的场景:

修改ResourceService的getResource方法:

@Override
public Mono<String> getResource(ResourceType resourceType) {
    Mono<ServerCredential> credentialMono = credentialService.getServerCredential(resourceType);
    // 使用flatMap串联异步操作:当credentialMono拿到结果后,调用searchResource发起API请求
    return credentialMono.flatMap(this::searchResource);
}

补充优化:WebClient的复用

每次调用searchResource都创建新的WebClient实例会带来性能开销,建议通过WebClient.Builder复用配置(Spring Boot自动提供该Bean):

  1. 注入WebClient.Builder:
private final WebClient.Builder webClientBuilder;

// 构造方法注入
public ResourceServiceImpl(WebClient.Builder webClientBuilder) {
    this.webClientBuilder = webClientBuilder;
}
  1. 修改searchResource方法:
private Mono<String> searchResource(ServerCredential credential) {
    WebClient client = webClientBuilder.baseUrl(credential.getServer().getServerUrl()).build();
    return client.post()
            .accept(MediaType.APPLICATION_JSON)
            .contentType(MediaType.APPLICATION_JSON)
            // 如果需要发送请求体,添加.bodyValue(请求对象)
            .retrieve()
            .bodyToMono(String.class)
            .retry(RETRY_COUNT);
}

原理说明

  • flatMap会等待credentialMono成功发射ServerCredential对象,然后调用searchResource方法发起WebClient请求,返回新的Mono<String>。
  • 整个方法返回的Mono<String>会被控制器返回给WebFlux框架,框架会自动处理订阅、异步调度,等待API请求完成后将结果返回给客户端。

内容的提问来源于stack exchange,提问作者Jonathan Hagen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:57:38