博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webclient对reactor-netty的封装
阅读量:5895 次
发布时间:2019-06-19

本文共 5079 字,大约阅读时间需要 16 分钟。

本文主要研究一下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
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<ClientResponse>

spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/ExchangeFunctions.java

public Mono
exchange(ClientRequest request) { Assert.notNull(request, "'request' must not be null"); return this.connector .connect(request.method(), request.url(), clientHttpRequest -> request.writeTo(clientHttpRequest, this.strategies)) .log("org.springframework.web.reactive.function.client", Level.FINE) .map(clientHttpResponse -> new DefaultClientResponse(clientHttpResponse, this.strategies)); }
这里调用了ReactorClientHttpConnector的connect方法

spring-web-5.0.2.RELEASE-sources.jar!/org/springframework/http/client/reactive/ReactorClientHttpConnector.java

public Mono
connect(HttpMethod method, URI uri, Function
> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(adaptHttpMethod(method), uri.toString(), request -> requestCallback.apply(adaptRequest(method, uri, request))) .map(this::adaptResponse); }
connect方法最后调用的reactor-netty的HttpClient的request方法。

小结

spring 5的webflux部分主要基于reactor项目来的,WebClient也是基于reactor-netty来实现,主要是封装了一些UriSpec及其他便利方法。

接口见spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/WebClient.java

转载地址:http://otisx.baihongyu.com/

你可能感兴趣的文章