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]。