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 42a9479182..a3b0c49c2d 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 @@ -43,10 +43,10 @@ import org.springframework.util.StringValueResolver; import org.springframework.web.service.annotation.HttpExchange; /** - * Factory for creating a client proxy given an HTTP service interface with + * Factory to create a client proxy from an HTTP service interface with * {@link HttpExchange @HttpExchange} methods. * - *
This class is intended to be declared as a bean in a Spring configuration. + *
To create an instance, use static methods to obtain a {@link Builder Builder}.
*
* @author Rossen Stoyanchev
* @since 6.0
@@ -54,81 +54,98 @@ import org.springframework.web.service.annotation.HttpExchange;
*/
public final class HttpServiceProxyFactory implements InitializingBean, EmbeddedValueResolverAware {
- private final HttpClientAdapter clientAdapter;
+ @Nullable
+ private final BuilderInitializedFactory builderInitializedFactory;
@Nullable
- private List By default this is {@link DefaultFormattingConversionService}.
+ * @deprecated as of 6.0 RC1 in favor of using the Builder to initialize
+ * the HttpServiceProxyFactory instance.
*/
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
public void setConversionService(ConversionService conversionService) {
- this.conversionService = conversionService;
+ Assert.state(this.beanStyleFactory != null, "HttpServiceProxyFactory was created through the builder");
+ this.beanStyleFactory.setConversionService(conversionService);
}
/**
* Set the StringValueResolver to use for resolving placeholders and
* expressions in {@link HttpExchange#url()}.
* @param resolver the resolver to use
+ * @deprecated as of 6.0 RC1 in favor of using the Builder to initialize
+ * an HttpServiceProxyFactory instance.
*/
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
- this.embeddedValueResolver = resolver;
+ Assert.state(this.beanStyleFactory != null, "HttpServiceProxyFactory was created through the builder");
+ this.beanStyleFactory.setEmbeddedValueResolver(resolver);
}
/**
* Set the {@link ReactiveAdapterRegistry} to use to support different
* asynchronous types for HTTP service method return values.
* By default this is {@link ReactiveAdapterRegistry#getSharedInstance()}.
+ * @deprecated as of 6.0 RC1 in favor of using the Builder to initialize
+ * an HttpServiceProxyFactory instance.
*/
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
public void setReactiveAdapterRegistry(ReactiveAdapterRegistry registry) {
- this.reactiveAdapterRegistry = registry;
+ Assert.state(this.beanStyleFactory != null, "HttpServiceProxyFactory was created through the builder");
+ this.beanStyleFactory.setReactiveAdapterRegistry(registry);
}
/**
@@ -136,42 +153,22 @@ public final class HttpServiceProxyFactory implements InitializingBean, Embedded
* with a synchronous (blocking) method signature.
* By default this is 5 seconds.
* @param blockTimeout the timeout value
+ * @deprecated as of 6.0 RC1 in favor of using the Builder to initialize
+ * an HttpServiceProxyFactory instance.
*/
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
public void setBlockTimeout(Duration blockTimeout) {
- this.blockTimeout = blockTimeout;
+ Assert.state(this.beanStyleFactory != null, "HttpServiceProxyFactory was created through the builder");
+ this.beanStyleFactory.setBlockTimeout(blockTimeout);
}
@Override
+ @Deprecated
public void afterPropertiesSet() throws Exception {
-
- this.conversionService = (this.conversionService != null ?
- this.conversionService : new DefaultFormattingConversionService());
-
- this.argumentResolvers = initArgumentResolvers(this.conversionService);
- }
-
- private List By default this is {@link DefaultFormattingConversionService}.
+ * @return this same builder instance
+ */
+ public Builder conversionService(ConversionService conversionService) {
+ this.conversionService = conversionService;
+ return this;
+ }
+
+ /**
+ * Set the {@link StringValueResolver} to use for resolving placeholders
+ * and expressions embedded in {@link HttpExchange#url()}.
+ * @param embeddedValueResolver the resolver to use
+ * @return this same builder instance
+ */
+ public Builder embeddedValueResolver(StringValueResolver embeddedValueResolver) {
+ this.embeddedValueResolver = embeddedValueResolver;
+ return this;
+ }
+
+ /**
+ * Set the {@link ReactiveAdapterRegistry} to use to support different
+ * asynchronous types for HTTP service method return values.
+ * By default this is {@link ReactiveAdapterRegistry#getSharedInstance()}.
+ * @return this same builder instance
+ */
+ public Builder reactiveAdapterRegistry(ReactiveAdapterRegistry registry) {
+ this.reactiveAdapterRegistry = registry;
+ return this;
+ }
+
+ /**
+ * Configure how long to wait for a response for an HTTP service method
+ * with a synchronous (blocking) method signature.
+ * By default this is 5 seconds.
+ * @param blockTimeout the timeout value
+ * @return this same builder instance
+ */
+ public Builder blockTimeout(Duration blockTimeout) {
+ this.blockTimeout = blockTimeout;
+ return this;
+ }
+
+ /**
+ * Build the {@link HttpServiceProxyFactory} instance.
+ */
+ public HttpServiceProxyFactory build() {
+ Assert.notNull(this.clientAdapter, "HttpClientAdapter is required");
+
+ return new HttpServiceProxyFactory(
+ this.clientAdapter, initArgumentResolvers(),
+ this.embeddedValueResolver, this.reactiveAdapterRegistry,
+ (this.blockTimeout != null ? this.blockTimeout : Duration.ofSeconds(5)));
+ }
+
+ private List S createClient(Class serviceType) {
-
- List HttpServiceMethod createHttpServiceMethod(Class serviceType, Method method) {
- Assert.notNull(this.argumentResolvers,
- "No argument resolvers: afterPropertiesSet was not called");
+ /**
+ * Return an {@link HttpServiceProxyFactory} builder.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+
+ /**
+ * Builder to create an {@link HttpServiceProxyFactory}.
+ */
+ public static final class Builder {
+
+ @Nullable
+ private HttpClientAdapter clientAdapter;
+
+ @Nullable
+ private List S createClient(Class serviceType) {
+
+ List HttpServiceMethod createHttpServiceMethod(Class serviceType, Method method) {
+ Assert.notNull(this.argumentResolvers,
+ "No argument resolvers: afterPropertiesSet was not called");
+
+ return new HttpServiceMethod(
+ method, serviceType, this.argumentResolvers, this.clientAdapter,
+ this.embeddedValueResolver, this.reactiveAdapterRegistry, this.blockTimeout);
+ }
+
+ }
+
+
+ /**
+ * Temporary class to support bean-style initialization during deprecation period.
+ */
+ private static final class BeanStyleFactory implements InitializingBean, EmbeddedValueResolverAware {
+
+ private final HttpClientAdapter clientAdapter;
+
+ @Nullable
+ private List S createClient(Class serviceType) {
+
+ List HttpServiceMethod createHttpServiceMethod(Class serviceType, Method method) {
+ Assert.notNull(this.argumentResolvers,
+ "No argument resolvers: afterPropertiesSet was not called");
+
+ return new HttpServiceMethod(
+ method, serviceType, this.argumentResolvers, this.clientAdapter,
+ this.embeddedValueResolver, this.reactiveAdapterRegistry, this.blockTimeout);
+ }
+
+ }
+
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java
index e33220fe1d..2227002bb5 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java
@@ -42,8 +42,7 @@ class CookieValueArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java
index 23988e3641..b74c233f4f 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java
@@ -43,7 +43,7 @@ public class HttpMethodArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
proxyFactory.afterPropertiesSet();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java
index f926f52338..baac0af3b9 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java
@@ -64,7 +64,7 @@ public class HttpServiceMethodTests {
@BeforeEach
void setUp() throws Exception {
- this.proxyFactory = new HttpServiceProxyFactory(this.client);
+ this.proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.proxyFactory.afterPropertiesSet();
}
@@ -174,10 +174,10 @@ public class HttpServiceMethodTests {
}
@Test
- void typeAndMethodAnnotatedService() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.setEmbeddedValueResolver(value -> (value.equals("${baseUrl}") ? "/base" : value));
- proxyFactory.afterPropertiesSet();
+ void typeAndMethodAnnotatedService() {
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client)
+ .embeddedValueResolver(value -> (value.equals("${baseUrl}") ? "/base" : value))
+ .build();
MethodLevelAnnotatedService service = proxyFactory.createClient(TypeAndMethodLevelAnnotatedService.class);
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java
index f2029c47c8..1e710bc107 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java
@@ -61,8 +61,9 @@ class NamedValueArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.addCustomArgumentResolver(this.argumentResolver);
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client)
+ .customArgumentResolver(this.argumentResolver)
+ .build();
proxyFactory.afterPropertiesSet();
this.service = proxyFactory.createClient(Service.class);
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java
index 15d7e73ae8..2cd6283329 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java
@@ -41,7 +41,7 @@ class PathVariableArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
proxyFactory.afterPropertiesSet();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java
index 8c43676762..61ec118c22 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java
@@ -40,8 +40,7 @@ class RequestAttributeArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java
index a0bd8b51f0..1fe0d7b657 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java
@@ -45,8 +45,7 @@ public class RequestBodyArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java
index 99de8173c3..9dced7b6b5 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java
@@ -43,8 +43,7 @@ class RequestHeaderArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java
index 458c1f0f4a..e663a4cfbf 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java
@@ -45,8 +45,7 @@ public class RequestParamArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
diff --git a/spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java
index 5089db6179..dc1a55f7e2 100644
--- a/spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java
+++ b/spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java
@@ -40,8 +40,7 @@ public class UrlArgumentResolverTests {
@BeforeEach
void setUp() throws Exception {
- HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client);
- proxyFactory.afterPropertiesSet();
+ HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
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 3ad530d4a6..c62e255028 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
@@ -124,6 +124,15 @@ public final class WebClientAdapter implements HttpClientAdapter {
}
+ /**
+ * 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);
+ }
+
/**
* Static method to create a {@link HttpServiceProxyFactory} configured to
* use the given {@link WebClient} instance. Effectively a shortcut for:
@@ -133,7 +142,11 @@ public final class WebClientAdapter implements HttpClientAdapter {
*
* @param webClient the client to use
* @return the created {@code HttpServiceProxyFactory} instance
+ * @deprecated in favor of using {@link #forClient(WebClient)} and
+ * {@link HttpServiceProxyFactory#builder(HttpClientAdapter)}
*/
+ @SuppressWarnings("removal")
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
public static HttpServiceProxyFactory createHttpServiceProxyFactory(WebClient webClient) {
return new HttpServiceProxyFactory(new WebClientAdapter(webClient));
}
@@ -143,18 +156,12 @@ public final class WebClientAdapter implements HttpClientAdapter {
* 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
+ * @deprecated in favor of using {@link #forClient(WebClient)} and
+ * {@link HttpServiceProxyFactory#builder(HttpClientAdapter)}
*/
+ @Deprecated(since = "6.0.0-RC1", forRemoval = true)
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 a05862eed4..9934cc7d0e 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
@@ -105,10 +105,11 @@ public class WebClientHttpServiceProxyTests {
return initHttpService(webClient);
}
- private TestHttpService initHttpService(WebClient webClient) throws Exception {
- HttpServiceProxyFactory factory = WebClientAdapter.createHttpServiceProxyFactory(webClient);
- factory.afterPropertiesSet();
- return factory.createClient(TestHttpService.class);
+ private TestHttpService initHttpService(WebClient webClient) {
+ return HttpServiceProxyFactory.builder()
+ .clientAdapter(WebClientAdapter.forClient(webClient))
+ .build()
+ .createClient(TestHttpService.class);
}
private void prepareResponse(Consumer