webclient对reactor-netty的封装
Posted 码匠的流水账
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webclient对reactor-netty的封装相关的知识,希望对你有一定的参考价值。
序
本文主要研究一下spring 5的WebClient对reactor-netty的HttpClient的封装
DefaultWebClientBuilder
spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java
@Override
public WebClient build() {
ExchangeFunction exchange = initExchangeFunction();
ExchangeFunction filteredExchange = (this.filters != null ? this.filters.stream()
.reduce(ExchangeFilterFunction::andThen)
.map(filter -> filter.apply(exchange))
.orElse(exchange) : exchange);
return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
unmodifiableCopy(this.defaultHeaders), unmodifiableCopy(this.defaultCookies),
new DefaultWebClientBuilder(this));
}
这里的build调用了initExchangeFunction方法
private ExchangeFunction initExchangeFunction() {
if (this.exchangeFunction != null) {
return this.exchangeFunction;
}
else if (this.connector != null) {
return ExchangeFunctions.create(this.connector, this.exchangeStrategies);
}
else {
return ExchangeFunctions.create(new ReactorClientHttpConnector(), this.exchangeStrategies);
}
}
这里new了一个ReactorClientHttpConnector
ReactorClientHttpConnector
spring-web-5.0.2.RELEASE-sources.jar!/org/springframework/http/client/reactive/ReactorClientHttpConnector.java
/**
* Create a Reactor Netty {@link ClientHttpConnector}
* with default {@link ClientOptions} and HTTP compression support enabled.
*/
public ReactorClientHttpConnector() {
this.httpClient = HttpClient.builder()
.options(options -> options.compression(true))
.build();
}
可以看到这个构造器使用了reactor/ipc/netty/http/client/HttpClient
DefaultWebClient
spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/DefaultWebClient.java
@Override
public RequestHeadersUriSpec<?> get() {
return methodInternal(HttpMethod.GET);
}
@Override
public RequestHeadersUriSpec<?> head() {
return methodInternal(HttpMethod.HEAD);
}
@Override
public RequestBodyUriSpec post() {
return methodInternal(HttpMethod.POST);
}
@Override
public RequestBodyUriSpec put() {
return methodInternal(HttpMethod.PUT);
}
@Override
public RequestBodyUriSpec patch() {
return methodInternal(HttpMethod.PATCH);
}
@Override
public RequestHeadersUriSpec<?> delete() {
return methodInternal(HttpMethod.DELETE);
}
@Override
public RequestHeadersUriSpec<?> options() {
return methodInternal(HttpMethod.OPTIONS);
}
@Override
public RequestBodyUriSpec method(HttpMethod httpMethod) {
return methodInternal(httpMethod);
}
@SuppressWarnings("unchecked")
private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) {
return new DefaultRequestBodyUriSpec(httpMethod);
}
DefaultWebClient主要对GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS方法封装返回RequestHeadersUriSpec或者RequestBodyUriSpec
@Override
public Mono<ClientResponse> exchange() {
ClientRequest request = (this.inserter != null ?
initRequestBuilder().body(this.inserter).build() :
initRequestBuilder().build());
return exchangeFunction.exchange(request).switchIfEmpty(NO_HTTP_CLIENT_RESPONSE_ERROR);
}
最后在exchange方法里头封装了对exchangeFunction的调用,这里的switchIfEmpty返回的是reactor.core.publisher.MonoSwitchIfEmpty
而exchangeFunction底层又是调用reactor-netty的HttpClient
小结
spring 5的webflux部分主要基于reactor项目来的,WebClient也是基于reactor-netty来实现,主要是封装了一些UriSpec及其他便利方法。
接口见spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/WebClient.java
以上是关于webclient对reactor-netty的封装的主要内容,如果未能解决你的问题,请参考以下文章
聊聊reactor-netty的PoolResources的两种模式