Mono 功能介绍与使用示例
一、核心概念与特性
Mono 是 Spring Reactor 框架中的核心组件,属于响应式编程(Reactive Programming)模型,专注于处理包含 0 或 1 个元素 的异步序列[1][2][5]。其核心特点包括:
- 异步非阻塞:通过 Reactive Streams 规范实现,适用于高并发场景[1][5]。
- 冷信号:仅在订阅(
subscribe
)时执行,支持延迟计算[1][4]。 - 资源高效:相比传统多线程模型,Mono 通过事件驱动减少资源消耗[1]。
二、核心功能与操作符
1. 创建 Mono 实例
Mono.just(T value)
:创建包含单个值的 Mono[1][2]。Mono<String> mono = Mono.just("Hello, Mono!");
Mono.empty()
:创建空 Mono,表示无返回值[1][4]。Mono<Void> emptyMono = Mono.empty();
- 从异步源创建:支持
Mono.fromCallable()
、Mono.fromCompletionStage()
等[1][3]。Mono<String> mono = Mono.fromCallable(() -> {Thread.sleep(1000); // 模拟延迟return "Async Result"; });
2. 转换与映射
map(Function)
:对值进行转换[1][2]。mono.map(s -> s.toUpperCase()).subscribe(System.out::println); // 输出 "HELLO, MONO!"
flatMap(Function)
:处理嵌套 Mono,展平结果[2][5]。Mono<String> result = mono.flatMap(s -> Mono.just(s + " Processed"));
3. 过滤与默认值
filter(Predicate)
:基于条件过滤值[1][4]。Mono<String> filtered = mono.filter(s -> s.startsWith("H"));
defaultIfEmpty(T defaultValue)
:当 Mono 为空时提供默认值[2][5]。Mono.empty().defaultIfEmpty("Default Value").subscribe(System.out::println);
4. 错误处理
onErrorReturn(T fallback)
:捕获异常并返回备用值[1][4]。Mono.error(new RuntimeException("Error")).onErrorReturn("Fallback Value").subscribe(System.out::println); // 输出 "Fallback Value"
onErrorResume(Function)
:捕获异常后继续执行另一个 Mono[2][5]。Mono.error(new RuntimeException("Error")).onErrorResume(e -> Mono.just("Recovered")).subscribe(System.out::println); // 输出 "Recovered"
5. 组合与终端操作
- 组合多个 Mono:使用
concatWith
或zipWith
[3][4]。Mono<String> combined = user1.concatWith(user2); // 依次执行
- 终端操作:强制同步获取结果[1][5]。
String result = mono.block(); // 阻塞等待结果
三、使用场景与示例
场景 1:异步数据库查询
public Mono<User> getUserById(String id) {return Mono.fromCallable(() -> {// 模拟数据库访问Thread.sleep(500);return new User(id, "John Doe");});
}// 调用链
getUserById("123").map(User::getName).flatMap(name -> Mono.just("Hello, " + name)).subscribe(System.out::println); // 输出 "Hello, John Doe"
场景 2:异常处理与默认值
Mono<String> errorMono = Mono.error(new IllegalArgumentException("Invalid ID"));errorMono.onErrorReturn("Default User").subscribe(result -> System.out.println("Result: " + result)); // 输出 "Result: Default User"
场景 3:定时任务与延迟执行
Mono<String> delayedMono = Mono.just("Delayed Response").delayElement(Duration.ofSeconds(2)); // 延迟 2 秒delayedMono.subscribe(result -> System.out.println("Received: " + result));
四、优势总结
- 简化异步代码:通过链式调用替代回调地狱[1][3]。
- 高效资源利用:冷信号机制避免无效计算,适合高并发[1][5]。
- 灵活的错误处理:提供多种异常恢复策略[2][4]。
注意:Mono 与 Flux 的核心区别在于 Flux 可处理 0 到 N 个元素,而 Mono 仅针对单一或空值场景[3][5]。