Skip to content

Commit

Permalink
Add static factory methods to WebClientAdapter
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rstoyanchev committed Jun 24, 2022
1 parent 45ee791 commit b72ee5f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
Expand Up @@ -50,6 +50,7 @@
*
* @author Rossen Stoyanchev
* @since 6.0
* @see org.springframework.web.reactive.function.client.support.WebClientAdapter
*/
public final class HttpServiceProxyFactory implements InitializingBean, EmbeddedValueResolverAware {

Expand All @@ -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");
Expand Down
Expand Up @@ -29,20 +29,28 @@
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;
}

Expand Down Expand Up @@ -116,4 +124,38 @@ else if (requestValues.getBody() != null) {
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);
}

}
Expand Up @@ -106,10 +106,9 @@ private TestHttpService initHttpService() throws Exception {
}

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) {
Expand Down
10 changes: 3 additions & 7 deletions src/docs/asciidoc/integration.adoc
Expand Up @@ -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:
Expand Down

0 comments on commit b72ee5f

Please sign in to comment.