From b72ee5f0345efd281716ce95b63bfb492df1ddbd Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Thu, 23 Jun 2022 12:34:29 +0100 Subject: [PATCH] Add static factory methods to WebClientAdapter Ideally one would pass WebClient directly to HttpServiceProxyFactory, but two need to remain decoupled. This commit adds static, shortcut methods to WebClientAdapter to create an HttpServiceProxyFactory, thus eliminating the step to wrap the WebClient. --- .../invoker/HttpServiceProxyFactory.java | 2 + .../client/support/WebClientAdapter.java | 48 +++++++++++++++++-- .../WebClientHttpServiceProxyTests.java | 7 ++- src/docs/asciidoc/integration.adoc | 10 ++-- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceProxyFactory.java b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceProxyFactory.java index 30d8029346..42a9479182 100644 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceProxyFactory.java +++ b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceProxyFactory.java @@ -50,6 +50,7 @@ import org.springframework.web.service.annotation.HttpExchange; * * @author Rossen Stoyanchev * @since 6.0 + * @see org.springframework.web.reactive.function.client.support.WebClientAdapter */ public final class HttpServiceProxyFactory implements InitializingBean, EmbeddedValueResolverAware { @@ -75,6 +76,7 @@ public final class HttpServiceProxyFactory implements InitializingBean, Embedded /** * Create an instance with the underlying HTTP client to use. * @param clientAdapter an adapter for the client + * @see org.springframework.web.reactive.function.client.support.WebClientAdapter#createHttpServiceProxyFactory(org.springframework.web.reactive.function.client.WebClient) */ public HttpServiceProxyFactory(HttpClientAdapter clientAdapter) { Assert.notNull(clientAdapter, "HttpClientAdapter is required"); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/support/WebClientAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/support/WebClientAdapter.java index f9d9f7c90b..c4f1ac590f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/support/WebClientAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/support/WebClientAdapter.java @@ -29,20 +29,28 @@ import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.service.invoker.HttpClientAdapter; import org.springframework.web.service.invoker.HttpRequestValues; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; /** - * {@link HttpClientAdapter} implementation for {@link WebClient}. + * {@link HttpClientAdapter} that enables an {@link HttpServiceProxyFactory} to + * use {@link WebClient} for request execution. + * + *

Use static factory methods in this class to create an + * {@code HttpServiceProxyFactory} configured with a given {@code WebClient}. * * @author Rossen Stoyanchev * @since 6.0 */ -public class WebClientAdapter implements HttpClientAdapter { +public final class WebClientAdapter implements HttpClientAdapter { private final WebClient webClient; - public WebClientAdapter(WebClient webClient) { + /** + * Package private constructor. See static factory methods. + */ + private WebClientAdapter(WebClient webClient) { this.webClient = webClient; } @@ -116,4 +124,38 @@ public class WebClientAdapter implements HttpClientAdapter { return bodySpec; } + + /** + * Static method to create a {@link HttpServiceProxyFactory} configured to + * use the given {@link WebClient} instance. Effectively a shortcut for: + *

+	 * WebClientAdapter adapter = WebClientAdapter.forClient(webClient);
+	 * HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(adapter);
+	 * 
+ * @param webClient the client to use + * @return the created {@code HttpServiceProxyFactory} instance + */ + public static HttpServiceProxyFactory createHttpServiceProxyFactory(WebClient webClient) { + return new HttpServiceProxyFactory(new WebClientAdapter(webClient)); + } + + /** + * Variant of {@link #createHttpServiceProxyFactory(WebClient)} that accepts + * a {@link WebClient.Builder} and uses it to create the client. + * @param webClientBuilder a builder to create the client to use with + * @return the created {@code HttpServiceProxyFactory} instance + */ + public static HttpServiceProxyFactory createHttpServiceProxyFactory(WebClient.Builder webClientBuilder) { + return createHttpServiceProxyFactory(webClientBuilder.build()); + } + + /** + * Create a {@link WebClientAdapter} for the given {@code WebClient} instance. + * @param webClient the client to use + * @return the created adapter instance + */ + public static WebClientAdapter forClient(WebClient webClient) { + return new WebClientAdapter(webClient); + } + } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java index 1de7120ca9..a05862eed4 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java @@ -106,10 +106,9 @@ public class WebClientHttpServiceProxyTests { } private TestHttpService initHttpService(WebClient webClient) throws Exception { - WebClientAdapter client = new WebClientAdapter(webClient); - HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(client); - proxyFactory.afterPropertiesSet(); - return proxyFactory.createClient(TestHttpService.class); + HttpServiceProxyFactory factory = WebClientAdapter.createHttpServiceProxyFactory(webClient); + factory.afterPropertiesSet(); + return factory.createClient(TestHttpService.class); } private void prepareResponse(Consumer consumer) { diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 56b1e891a0..9a3ed6cf5f 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -390,14 +390,10 @@ the `WebClient`: [source,java,indent=0,subs="verbatim,quotes"] ---- - WebClient client = WebClient.builder() - .baseUrl("https://api.github.com/") - .build(); - - HttpServiceProxyFactory proxyFactory = - HttpServiceProxyFactory.builder(new WebClientAdapter(client)).build(); + WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build(); + HttpServiceProxyFactory factory = WebClientAdapter.createHttpServiceProxyFactory(client)).build(); - RepositoryService service = proxyFactory.createClient(RepositoryService.class); + RepositoryService service = factory.createClient(RepositoryService.class); ---- An HTTP service interface can declare common attributes at the type level: