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.
This commit is contained in:
rstoyanchev 2022-06-23 12:34:29 +01:00
parent 45ee7913bf
commit b72ee5f034
4 changed files with 53 additions and 14 deletions

View File

@ -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");

View File

@ -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.
*
* <p>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:
* <pre>
* WebClientAdapter adapter = WebClientAdapter.forClient(webClient);
* HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(adapter);
* </pre>
* @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);
}
}

View File

@ -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<MockResponse> consumer) {

View File

@ -390,14 +390,10 @@ the `WebClient`:
[source,java,indent=0,subs="verbatim,quotes"]
----
WebClient client = WebClient.builder()
.baseUrl("https://api.github.com/")
.build();
WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build();
HttpServiceProxyFactory factory = WebClientAdapter.createHttpServiceProxyFactory(client)).build();
HttpServiceProxyFactory proxyFactory =
HttpServiceProxyFactory.builder(new WebClientAdapter(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: