webclient对reactor-netty的封装
序本文主要研究一下spring 5的WebClient对reactor-netty的HttpClient的封装 DefaultWebClientBuilderspring-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 ReactorClientHttpConnectorspring-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 DefaultWebClientspring-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<ClientResponse> spring-webflux-5.0.2.RELEASE-sources.jar!/org/springframework/web/reactive/function/client/ExchangeFunctions.java public Mono<ClientResponse> 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<ClientHttpResponse> connect(HttpMethod method,URI uri,Function<? super ClientHttpRequest,Mono<Void>> 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 正则表达式 – 与R中的区域设置混淆
- ArcGIS Server 开发指南:基于Flex和.NET(4)——Flex与Java
- 浅析从vue源码看观察者模式
- oracle – 如何使dbms_metadata.get_ddl更漂亮/有用
- c# – Microsoft Edge忽略内容处置响应头的FileName属性?
- 如何确定Big O比较Ruby中的两个数组
- ruby-on-rails – 使用IP地址结束Rails 2 URL会导致路由错误
- react-native – 如何在React Native中显示图标?
- ruby-on-rails – 在哪里以及如何处理rails异常?
- ruby – Gemfile.lock始终没有分段进行更改