Spring WebFlux Flux 和Mono区别

编程教程 > Java > Spring (7) 2025-09-01 08:45:53

Flux Mono 区别说明

Flux Mono 是 Spring WebFlux 框架中用于响应式编程的核心类型,它们都来自于 Project Reactor 库。两者的主要区别在于它们所表示的数据流的数量和完成状态。

简单来说:

  • Flux<T>: 表示一个可以发出 0 个到 N 个元素的异步数据流,之后可能(也可能不)以 onComplete 信号(成功完成)或 onError 信号(发生错误)结束。
  • Mono<T>: 表示一个最多发出 0 个或 1 个元素的异步数据流,之后可能(也可能不)以 onComplete onError 信号结束。

 

详细对比

特性 Flux<T> Mono<T>
发出元素数量 0 到 N 个 (多值流) 0 或 1 个 (单值流)
典型使用场景 - 获取资源列表 (如 GET /users)<br>- 事件流 (如 WebSocket 消息、服务器发送事件 SSE)<br>- 批量处理结果 - 获取单个资源 (如 GET /users/{id})<br>- 创建/更新/删除操作的响应 (通常返回状态或空)<br>- 认证、登录等返回单一结果的操作
类比 类似于 Stream<T>List<T>,但它是异步、非阻塞的 类似于 Optional<T>Future<T>/CompletableFuture<T>,但它是响应式、支持背压的
完成信号 可以发出 onCompleteonError 可以发出 onCompleteonError
空值表示 空的 Flux 表示没有元素,以 onComplete 结束。 空的 Mono 表示没有元素,以 onComplete 结束。可以用 Mono<Void> 表示无返回值的操作。
常用创建方法 Flux.just(T...), Flux.fromIterable(Iterable<T>), Flux.range(start, count), Flux.create() Mono.just(T), Mono.justOrEmpty(T), Mono.fromCallable(() -> T), Mono.empty(), Mono.error(Throwable)
常用转换/操作 map, flatMap, filter, concatMap, switchMap, collectList, collectMap, zip (多个Flux) 等 map, flatMap, switchIfEmpty, defaultIfEmpty, thenReturn, zipWith (与另一个Mono) 等

代码示例

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
// --- Mono 示例 ---
// 1. 发出一个值
Mono<String> singleName = Mono.just("Alice");
singleName.subscribe(name -> System.out.println("Hello, " + name)); // 输出: Hello, Alice
// 2. 可能发出一个值,也可能为空
Mono<String> possiblyEmpty = Mono.justOrEmpty(getUserNameFromDatabase()); // 如果getUserNameFromDatabase()返回null,则Mono为空
possiblyEmpty
    .defaultIfEmpty("Guest") // 如果为空,则使用默认值
    .subscribe(name -> System.out.println("User: " + name));
// 3. 表示一个无返回值的操作 (如保存)
Mono<Void> saveOperation = saveUserToDatabase(user);
saveOperation
    .then(Mono.just("User saved successfully")) // 操作完成后,发出成功消息
    .subscribe(message -> System.out.println(message));
// --- Flux 示例 ---
// 1. 发出多个值
Flux<String> names = Flux.just("Alice", "Bob", "Charlie");
names.subscribe(name -> System.out.println("Name: " + name)); // 输出三行
// 2. 从集合创建
List<String> nameList = Arrays.asList("David", "Eve", "Frank");
Flux<String> namesFromList = Flux.fromIterable(nameList);
namesFromList.subscribe(System.out::println);
// 3. 处理数据库查询返回的多条记录
Flux<User> users = userRepository.findAll(); // 假设返回Flux<User>
users
    .filter(user -> user.getAge() > 18)
    .map(User::getName)
    .collectList() // 将所有名字收集到一个List中
    .subscribe(adultNames -> System.out.println("Adults: " + adultNames));
// 4. 事件流 (概念性)
Flux<String> eventStream = getWebSocketMessageFlux(); // 持续接收消息
eventStream.subscribe(message -> System.out.println("Received: " + message));

总结

选择 Flux 还是 Mono 主要取决于你的业务逻辑预期返回多少个元素:

  • 当你明确知道结果是零个或一个时**,使用 Mono<T>。这提供了更好的语义清晰度,并且可以使用 Mono 特有的操作符(如 defaultIfEmpty, switchIfEmpty)来优雅地处理空值情况。
  • 当你预期结果是零个、一个或多个时,使用 Flux<T>。它提供了处理多个元素的强大操作符。

在 Spring WebFlux 的 @RestController 中,你的 @GetMapping, @PostMapping 等方法的返回类型通常就是 Mono<T> (用于单个资源) 或 Flux<T> (用于资源集合)。

 
 

 

 


评论
User Image
提示:请评论与当前内容相关的回复,广告、推广或无关内容将被删除。

相关文章
Flux 和 Mono 区别说明Flux 和 Mono 是 Spring WebFlux 框架中用于响应式编程的核心类型,它们都来自于 Project Reac
在 Spring WebFlux 中,当 Controller 返回 Flux 时,前端可以通过多种方式接收这个异步、流式的数据。最常见和推荐的方式是使用 Se
Spring WebFlux,spring框架5.0将会新增的web增强框架,这里主要讲述什么是Spring WebFlux以及Spring WebFlux的新功能,Spring WebFlux...
1.引言Spring 5通过引入一种名为Spring WebFlux的全新反应框架来支持响应式编程范例
Spring WebFlux 项目实战 在Spring WebFlux中创建多个RouterFunctions,在这篇文章中,我们将着眼于在Spring WebFlux中将多个路由器功能定义到不...
spring boot webflux client实战,webclient是spring webflux的一个小组件。对于Java的http通讯来说,webclient是非常简单易用的。
引言Spring Boot 2.0最近去了GA,所以我决定写我关于Spring的第一篇文章很长一段时间
Spring WebFlux入门程序hello word。本文主要在于讲解如何创建和运行spring webflux入门程序hello word。其实不难发现和spring mvc相比代码层基本...
Spring Context 与Spring MVC Context那些坑
1.引言Spring开发人员,您是否曾经觉得需要一个易于使用且高效的流畅功能样式 API 的异步/非阻塞 HTTP客户端?如果是,那么我欢迎您阅读关于WebClient的文章,WebClient...
从Spring 6和Spring Boot 3开始,Spring framework支持将远程HTTP服务代理为带有HTTP交换注解方法的Java接口。类似的库,如OpenFeign和Retro...
spring boot mybatis 整合使用讲解介绍,spring boot与MyBatis的使用讲解介绍。spring boot mybatis xml mapper方式的入门和通过一个简...
从Spring 6和Spring Boot 3开始,与OpenFeign和Retrofit等其他声明式客户端类似,Spring框架支持以Java接口的形式创建RSocket服务,并为RSocke...
Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。