Spring WebFlux PUT接口消费Mono后业务逻辑未执行问题求助
问题分析与解决方案
你遇到的问题核心是在WebFlux中错误地手动调用了subscribe(),这完全破坏了响应式流的驱动逻辑。
为什么doSomeThing()和println没执行?
Reactor的流是冷流,只有当被订阅时才会触发执行。但在WebFlux的请求处理流程中,框架是通过订阅你返回的Mono<ServerResponse>来驱动整个响应链的。你现在手动调用subscribe()的流,和返回的Mono.empty()完全是两个独立的流:
- 框架只会订阅你返回的空Mono,它不会触发你手动subscribe的那个流;
- 即使手动subscribe的流偶尔执行,也不受WebFlux请求生命周期的管理,可能在请求已经结束后才运行,导致你看不到输出。
修正后的代码
你需要把所有操作整合到返回的响应式链中,让框架来统一驱动订阅:
import org.springframework.http.MediaType; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; public Mono<ServerResponse> updateProduct(ServerRequest request){ // 把所有操作串联到同一个响应链中 return request.bodyToMono(Product.class) .flatMap(item -> { // 执行你的业务操作 doSomeThing(item); System.out.println("Called or not called!!"); // 如果productService.product是数据库更新操作(建议返回Mono类型),直接返回它 return Mono.just(productService.product); }) // 使用then()忽略前面的结果,返回空响应体 .then(ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .body(Mono.empty(), Product.class)); }
额外注意事项
如果doSomeThing()是阻塞/耗时操作,一定要把它包装成异步操作,避免阻塞WebFlux的事件循环线程,比如:
.flatMap(item -> Mono.fromCallable(() -> { doSomeThing(item); // 阻塞操作 return productService.product; }).subscribeOn(Schedulers.boundedElastic()))
这样修改后,你的业务代码会在框架订阅返回的Mono<ServerResponse>时被触发执行,就能看到预期的输出了。
内容的提问来源于stack exchange,提问作者Abdelhafid
相关产品推荐
相关产品推荐

