diff --git a/spring/webflux/Reactor.md b/spring/webflux/Reactor.md index dded082..4ecd3ec 100644 --- a/spring/webflux/Reactor.md +++ b/spring/webflux/Reactor.md @@ -94,6 +94,7 @@ - [prefetch](#prefetch-1) - [zip](#zip) - [zipWith](#zipwith) + - [defer](#defer) # Reactor ## Reactive Programming @@ -1363,3 +1364,8 @@ prefetch用于控制每个inner publisher在途的元素上限 #### zipWith `zipWith`可以将当前flux和另一个publisher一起执行`zip`操作。 +### defer +`Mono.defer`会创建一个Mono对象a,每次每次Mono对象a被下游调用`subscribe`时,都会通过`supplier`生成一个新的Mono对象b,下游实际订阅的是新的Mono对象b。 + + + diff --git a/spring/webflux/webclient.md b/spring/webflux/webclient.md index bb65aec..21d3e9e 100644 --- a/spring/webflux/webclient.md +++ b/spring/webflux/webclient.md @@ -469,6 +469,55 @@ client.get().uri("https://example.org/") ``` 除此之外,可以通过`org.springframework.web.reactive.function.client.DefaultWebClientBuilder#defaultRequest`方法为`webClient`注册一个callback回调,该回调可为所有请求插入attribute。 +## Context +通过attribute,可以便捷的向filter chain传递细信息。但是,`attribute`针对的范围是`当前请求`。 +如果想要在`subscription`的范围内(例如,flatMap或concatMap等),可以使用`Reactor Context`。 +使用示例如下所示: +```java +WebClient client = WebClient.builder() + .filter((request, next) -> + Mono.deferContextual(contextView -> { + String value = contextView.get("foo"); + // ... + })) + .build(); +client.get().uri("https://example.org/") + .retrieve() + .bodyToMono(String.class) + .flatMap(body -> { + // perform nested request (context propagates automatically)... + }) + .contextWrite(context -> context.put("foo", ...)); +``` + +## Synchronous Use +webclient同样支持同步使用,示例如下: +```java +Person person = client.get().uri("/person/{id}", i).retrieve() + .bodyToMono(Person.class) + .block(); + +List persons = client.get().uri("/persons").retrieve() + .bodyToFlux(Person.class) + .collectList() + .block(); +``` +对多个`Publisher`的操作进行zip的示例如下: +```java +Mono personMono = client.get().uri("/person/{id}", personId) + .retrieve().bodyToMono(Person.class); + +Mono> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId) + .retrieve().bodyToFlux(Hobby.class).collectList(); + +Map data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> { + Map map = new LinkedHashMap<>(); + map.put("person", person); + map.put("hobbies", hobbies); + return map; + }) + .block(); +```