Spring Reactive API:从Mono<K>获取Flux<T>及非阻塞关联查询实现
Spring Reactive 相关问题解答
1. 如何从 Mono<K> 获取 Flux<T>?
其实从单个元素的Mono转成Flux有几种常用的方式,完全可以根据你的具体需求来选:
直接转换:用
flux()方法
如果你的Mono里有一个元素,直接调用flux()就能把它转换成只包含这一个元素的Flux;要是Mono是空的,得到的就是空的Flux。示例代码:Mono<String> monoStr = Mono.just("Hello"); Flux<String> fluxStr = monoStr.flux();基于Mono元素生成Flux:用
flatMapMany()
要是你需要用Mono里的元素来生成一个Flux(比如根据这个元素去查询多个关联结果),那flatMapMany()绝对是首选。它会订阅Mono,拿到元素后执行你提供的逻辑返回Flux,完美契合响应式的非阻塞流处理。示例:Mono<Integer> monoId = Mono.just(100); Flux<Item> itemFlux = monoId.flatMapMany(id -> itemService.findItemsByParentId(id));处理空Mono的情况:搭配
switchIfEmpty()
如果担心Mono可能为空,想要在空的时候返回一个默认的Flux,可以结合switchIfEmpty()来做:Mono<User> emptyMono = Mono.empty(); Flux<User> defaultFlux = emptyMono.flux().switchIfEmpty(Flux.just(new User("default")));
2. 持有 Mono<Property> 时,如何非阻塞获取对应的 Flux<Photo>?
这个场景太典型了!响应式编程里最忌讳用block(),因为它会把异步流硬生生阻塞成同步调用,完全违背了响应式非阻塞的核心设计。正确的做法就是用刚才提到的flatMapMany(),把Mono<Property>里的元素拿出来,再调用photoService的查询方法返回Flux<Photo>。
直接上代码示例:
// 假设你已经有一个Mono<Property>实例 Mono<Property> propertyMono = propertyService.findById(targetPropertyId); // 用flatMapMany实现非阻塞的关联查询 Flux<Photo> photoFlux = propertyMono.flatMapMany(property -> photoService.findByPropertyId(property.getId()) );
为什么这么做才对?
flatMapMany()会订阅propertyMono,当Mono发出Property元素时,它会立刻执行后面的查询逻辑并返回Flux<Photo>,整个过程都是异步非阻塞的,不会占用线程资源等待结果。- 要是用
block()的话,会强制等待Mono完成,把异步操作变成同步,不仅浪费线程资源,还可能在高并发场景下导致性能瓶颈,完全不符合响应式编程的最佳实践。
内容的提问来源于stack exchange,提问作者ace
相关产品推荐
相关产品推荐

