![](/img/trans.png)
[英]How can I use intellij to refactor a field into a try-with-resources
[英]How can I use the try-with-resources patter in reactor, if resource is a Mono?
我有一個客戶端,它被創建為 Mono,例如
Mono<MyClient> myClientMono =...
MyClient
class 實現Closeable
接口,因此您可以使用標准的 java try-with-resources 模式。
使用Mono
包裝的資源的最佳方式是什么?
如果資源是常規 object,如InputStream
,我了解如何使用 Mono.using() 來模擬 try-with-resources。
但是,如何確保 myclient 在與 Reactor 一起使用后被關閉?
我可以這樣做:
Mono.using(() -> myClientMono.block(),
myClient -> myClient.doSomething(),
myClient.close())
.subscribe(System.out::println);
但是,這將是阻塞的,不能在異步線程中使用。
我可以做這樣的事情並在使用后關閉客戶端:
myClientMono
.flatMap( myClient -> {
var a = myClient.doSomething();
myClient.close();
return Mono.just(a);
})
.subscribe(Sytem.out::println);
但是,如果發生錯誤,這不會關閉客戶端。
我想知道是否有更好的解決方案?
正確的解決方案是使用Mono.usingWhen或Flux.usingWhen 。
在這兩種情況下,您都提供了一個資源發布者,每次用戶訂閱時都會調用它來生成新資源。
讓我們看一個例子:
import java.time.Duration;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class UsingWhen {
/** Simulates a closeable resource. Prints a message when opening and closing. */
public static class ReactiveResourceMock implements AutoCloseable {
public ReactiveResourceMock() { System.out.println("OPENING"); }
Flux<Integer> content() { return Flux.range(1, 3); }
@Override
public void close() throws Exception { System.out.println("CLOSING"); };
}
/** Simulates async value opening */
public static Mono<ReactiveResourceMock> open() {
return Mono.delay(Duration.ofMillis(200))
.map(i -> new ReactiveResourceMock());
}
public static void main(String[] args) {
Mono<ReactiveResourceMock> openResource = open();
Flux<Integer> flow = Flux.usingWhen(
openResource,
ReactiveResourceMock::content,
resource -> Mono.fromCallable(() -> {
resource.close();
return 1;
}))
.doOnCancel(() -> System.out.println("CANCELLED"))
.doOnComplete(() -> System.out.println("COMPLETED"));
System.out.println("VERIFY FLOW CONTROL:");
flow.doOnNext(System.out::println)
.blockLast();
System.out.println("WHAT HAPPENS IN CASE OF ERROR:");
flow.limitRate(1)
.map(i -> i / (i % 2))
.onErrorReturn(-1)
.doOnNext(System.out::println)
.blockLast();
}
}
上面的程序打印:
VERIFY FLOW CONTROL:
OPENING
1
2
3
CLOSING
COMPLETED
WHAT HAPPENS IN CASE OF ERROR:
OPENING
1
CANCELLED
-1
CLOSING
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.