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<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

转载于:https://my.oschina.net/go4it/blog/1622133

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值