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 f8dcb081d5..1892913435 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 @@ -28,6 +28,8 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.MethodIntrospector; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -42,36 +44,133 @@ import org.springframework.web.service.annotation.HttpExchange; * Factory for creating a client proxy given an HTTP service interface with * {@link HttpExchange @HttpExchange} methods. * + *

This class is intended to be declared as a bean in a Spring configuration. + * * @author Rossen Stoyanchev * @since 6.0 */ -public final class HttpServiceProxyFactory { +public final class HttpServiceProxyFactory implements InitializingBean, EmbeddedValueResolverAware { private final HttpClientAdapter clientAdapter; - private final List argumentResolvers; + @Nullable + private List customArgumentResolvers; @Nullable - private final StringValueResolver embeddedValueResolver; + private List argumentResolvers; - private final ReactiveAdapterRegistry reactiveAdapterRegistry; + @Nullable + private ConversionService conversionService; - private final Duration blockTimeout; + @Nullable + private StringValueResolver embeddedValueResolver; + + private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance(); + + private Duration blockTimeout = Duration.ofSeconds(5); - private HttpServiceProxyFactory( - HttpClientAdapter clientAdapter, List argumentResolvers, - @Nullable StringValueResolver embeddedValueResolver, ReactiveAdapterRegistry reactiveAdapterRegistry, - Duration blockTimeout) { - + /** + * Create an instance with the underlying HTTP client to use. + * @param clientAdapter an adapter for the client + */ + public HttpServiceProxyFactory(HttpClientAdapter clientAdapter) { + Assert.notNull(clientAdapter, "HttpClientAdapter is required"); this.clientAdapter = clientAdapter; - this.argumentResolvers = argumentResolvers; - this.embeddedValueResolver = embeddedValueResolver; - this.reactiveAdapterRegistry = reactiveAdapterRegistry; + } + + + /** + * Register a custom argument resolver, invoked ahead of default resolvers. + * @param resolver the resolver to add + */ + public void addCustomArgumentResolver(HttpServiceArgumentResolver resolver) { + if (this.customArgumentResolvers == null) { + this.customArgumentResolvers = new ArrayList<>(); + } + this.customArgumentResolvers.add(resolver); + } + + /** + * Set the custom argument resolvers to use, ahead of default resolvers. + * @param resolvers the resolvers to use + */ + public void setCustomArgumentResolvers(List resolvers) { + this.customArgumentResolvers = new ArrayList<>(resolvers); + } + + /** + * Set the {@link ConversionService} to use where input values need to + * be formatted as Strings. + *

By default this is {@link DefaultFormattingConversionService}. + */ + public void setConversionService(ConversionService conversionService) { + this.conversionService = conversionService; + } + + /** + * Set the StringValueResolver to use for resolving placeholders and + * expressions in {@link HttpExchange#url()}. + * @param resolver the resolver to use + */ + @Override + public void setEmbeddedValueResolver(StringValueResolver resolver) { + this.embeddedValueResolver = 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()}. + */ + public void setReactiveAdapterRegistry(ReactiveAdapterRegistry registry) { + this.reactiveAdapterRegistry = registry; + } + + /** + * 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 + */ + public void setBlockTimeout(Duration blockTimeout) { this.blockTimeout = blockTimeout; } + @Override + public void afterPropertiesSet() throws Exception { + + this.conversionService = (this.conversionService != null ? + this.conversionService : new DefaultFormattingConversionService()); + + this.argumentResolvers = initArgumentResolvers(this.conversionService); + } + + private List initArgumentResolvers(ConversionService conversionService) { + List resolvers = new ArrayList<>(); + + // Custom + if (this.customArgumentResolvers != null) { + resolvers.addAll(this.customArgumentResolvers); + } + + // Annotation-based + resolvers.add(new RequestHeaderArgumentResolver(conversionService)); + resolvers.add(new RequestBodyArgumentResolver(this.reactiveAdapterRegistry)); + resolvers.add(new PathVariableArgumentResolver(conversionService)); + resolvers.add(new RequestParamArgumentResolver(conversionService)); + resolvers.add(new CookieValueArgumentResolver(conversionService)); + resolvers.add(new RequestAttributeArgumentResolver()); + + // Specific type + resolvers.add(new UrlArgumentResolver()); + resolvers.add(new HttpMethodArgumentResolver()); + + return resolvers; + } + + /** * Return a proxy that implements the given HTTP service interface to perform * HTTP requests and retrieve responses through an HTTP client. @@ -81,150 +180,25 @@ public final class HttpServiceProxyFactory { */ public S createClient(Class serviceType) { - List methods = - MethodIntrospector.selectMethods(serviceType, this::isExchangeMethod) - .stream() - .map(method -> - new HttpServiceMethod( - method, serviceType, this.argumentResolvers, this.clientAdapter, - this.embeddedValueResolver, this.reactiveAdapterRegistry, this.blockTimeout)) + List httpServiceMethods = + MethodIntrospector.selectMethods(serviceType, this::isExchangeMethod).stream() + .map(method -> createHttpServiceMethod(serviceType, method)) .toList(); - return ProxyFactory.getProxy(serviceType, new HttpServiceMethodInterceptor(methods)); + return ProxyFactory.getProxy(serviceType, new HttpServiceMethodInterceptor(httpServiceMethods)); } private boolean isExchangeMethod(Method method) { return AnnotatedElementUtils.hasAnnotation(method, HttpExchange.class); } + private HttpServiceMethod createHttpServiceMethod(Class serviceType, Method method) { + Assert.notNull(this.argumentResolvers, + "No argument resolvers: afterPropertiesSet was not called"); - /** - * Return a builder for an {@link HttpServiceProxyFactory}. - * @param adapter an adapter for the underlying HTTP client - * @return the builder - */ - public static Builder builder(HttpClientAdapter adapter) { - return new Builder(adapter); - } - - - /** - * Builder for {@link HttpServiceProxyFactory}. - */ - public final static class Builder { - - private final HttpClientAdapter clientAdapter; - - private final List customResolvers = new ArrayList<>(); - - @Nullable - private ConversionService conversionService; - - @Nullable - private StringValueResolver embeddedValueResolver; - - private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance(); - - private Duration blockTimeout = Duration.ofSeconds(5); - - private Builder(HttpClientAdapter clientAdapter) { - Assert.notNull(clientAdapter, "HttpClientAdapter is required"); - this.clientAdapter = clientAdapter; - } - - /** - * Register a custom argument resolver. This will be inserted ahead of - * default resolvers. - * @return the same builder instance - */ - public Builder addCustomResolver(HttpServiceArgumentResolver resolver) { - this.customResolvers.add(resolver); - return this; - } - - /** - * Set the {@link ConversionService} to use where input values need to - * be formatted as Strings. - *

By default this is {@link DefaultFormattingConversionService}. - * @return the same builder instance - */ - public Builder setConversionService(ConversionService conversionService) { - this.conversionService = conversionService; - return this; - } - - /** - * Set the StringValueResolver to use for resolving placeholders and - * expressions in {@link HttpExchange#url()}. - * @param embeddedValueResolver the resolver to use - * @return the same builder instance - * @see org.springframework.context.EmbeddedValueResolverAware - */ - public Builder setEmbeddedValueResolver(@Nullable 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 the same builder instance - */ - public Builder setReactiveAdapterRegistry(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 the same builder instance - */ - public Builder setBlockTimeout(Duration blockTimeout) { - this.blockTimeout = blockTimeout; - return this; - } - - /** - * Build and return the {@link HttpServiceProxyFactory} instance. - */ - public HttpServiceProxyFactory build() { - - ConversionService conversionService = initConversionService(); - List resolvers = initArgumentResolvers(conversionService); - - return new HttpServiceProxyFactory( - this.clientAdapter, resolvers, this.embeddedValueResolver, this.reactiveAdapterRegistry, - this.blockTimeout); - } - - private ConversionService initConversionService() { - return (this.conversionService != null ? - this.conversionService : new DefaultFormattingConversionService()); - } - - private List initArgumentResolvers(ConversionService conversionService) { - - List resolvers = new ArrayList<>(this.customResolvers); - - // Annotation-based - resolvers.add(new RequestHeaderArgumentResolver(conversionService)); - resolvers.add(new RequestBodyArgumentResolver(this.reactiveAdapterRegistry)); - resolvers.add(new PathVariableArgumentResolver(conversionService)); - resolvers.add(new RequestParamArgumentResolver(conversionService)); - resolvers.add(new CookieValueArgumentResolver(conversionService)); - resolvers.add(new RequestAttributeArgumentResolver()); - - // Specific type - resolvers.add(new UrlArgumentResolver()); - resolvers.add(new HttpMethodArgumentResolver()); - - return resolvers; - } - + 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 802d6169b0..e33220fe1d 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 @@ -18,6 +18,7 @@ package org.springframework.web.service.invoker; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.util.ObjectUtils; @@ -36,7 +37,15 @@ class CookieValueArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } // Base class functionality should be tested in NamedValueArgumentResolverTests. 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 2bdbaec14b..57d6b02016 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 @@ -16,6 +16,7 @@ package org.springframework.web.service.invoker; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; @@ -34,7 +35,15 @@ public class HttpMethodArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } @Test 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 5046471001..ea8711b395 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 @@ -21,6 +21,7 @@ import java.util.Optional; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Single; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -56,9 +57,16 @@ public class HttpServiceMethodTests { private static final ParameterizedTypeReference BODY_TYPE = new ParameterizedTypeReference<>() {}; - private final TestHttpClientAdapter clientAdapter = new TestHttpClientAdapter(); + private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.clientAdapter).build(); + private HttpServiceProxyFactory proxyFactory; + + + @BeforeEach + void setUp() throws Exception { + this.proxyFactory = new HttpServiceProxyFactory(this.client); + this.proxyFactory.afterPropertiesSet(); + } @Test @@ -150,7 +158,7 @@ public class HttpServiceMethodTests { service.performGet(); - HttpRequestValues requestValues = this.clientAdapter.getRequestValues(); + HttpRequestValues requestValues = this.client.getRequestValues(); assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.GET); assertThat(requestValues.getUriTemplate()).isEqualTo(""); assertThat(requestValues.getHeaders().getContentType()).isNull(); @@ -158,7 +166,7 @@ public class HttpServiceMethodTests { service.performPost(); - requestValues = this.clientAdapter.getRequestValues(); + requestValues = this.client.getRequestValues(); assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.POST); assertThat(requestValues.getUriTemplate()).isEqualTo("/url"); assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); @@ -166,17 +174,17 @@ public class HttpServiceMethodTests { } @Test - void typeAndMethodAnnotatedService() { + void typeAndMethodAnnotatedService() throws Exception { - HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.clientAdapter) - .setEmbeddedValueResolver(value -> (value.equals("${baseUrl}") ? "/base" : value)) - .build(); + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.setEmbeddedValueResolver(value -> (value.equals("${baseUrl}") ? "/base" : value)); + proxyFactory.afterPropertiesSet(); MethodLevelAnnotatedService service = proxyFactory.createClient(TypeAndMethodLevelAnnotatedService.class); service.performGet(); - HttpRequestValues requestValues = this.clientAdapter.getRequestValues(); + HttpRequestValues requestValues = this.client.getRequestValues(); assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.GET); assertThat(requestValues.getUriTemplate()).isEqualTo("/base"); assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_CBOR); @@ -184,7 +192,7 @@ public class HttpServiceMethodTests { service.performPost(); - requestValues = this.clientAdapter.getRequestValues(); + requestValues = this.client.getRequestValues(); assertThat(requestValues.getHttpMethod()).isEqualTo(HttpMethod.POST); assertThat(requestValues.getUriTemplate()).isEqualTo("/base/url"); assertThat(requestValues.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); @@ -192,8 +200,8 @@ public class HttpServiceMethodTests { } private void verifyClientInvocation(String methodName, @Nullable ParameterizedTypeReference expectedBodyType) { - assertThat((this.clientAdapter.getInvokedMethodName())).isEqualTo(methodName); - assertThat(this.clientAdapter.getBodyType()).isEqualTo(expectedBodyType); + assertThat((this.client.getInvokedMethodName())).isEqualTo(methodName); + assertThat(this.client.getBodyType()).isEqualTo(expectedBodyType); } 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 c1931329e1..25b5727789 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 @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Optional; import org.apache.groovy.util.Maps; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.MethodParameter; @@ -53,11 +54,17 @@ class NamedValueArgumentResolverTests { private final TestNamedValueArgumentResolver argumentResolver = new TestNamedValueArgumentResolver(); - private final Service service = - HttpServiceProxyFactory.builder(this.client) - .addCustomResolver(this.argumentResolver) - .build() - .createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.addCustomArgumentResolver(this.argumentResolver); + proxyFactory.afterPropertiesSet(); + + this.service = proxyFactory.createClient(Service.class); + } @Test 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 0f29856b8b..15d7e73ae8 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 @@ -16,6 +16,7 @@ package org.springframework.web.service.invoker; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.lang.Nullable; @@ -35,7 +36,15 @@ class PathVariableArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } // Base class functionality should be tested in NamedValueArgumentResolverTests. 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 e020b2bf6a..8c43676762 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 @@ -16,6 +16,7 @@ package org.springframework.web.service.invoker; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.lang.Nullable; @@ -34,7 +35,15 @@ class RequestAttributeArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } // Base class functionality should be tested in NamedValueArgumentResolverTests. 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 31142b7cb0..a0bd8b51f0 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 @@ -18,6 +18,7 @@ package org.springframework.web.service.invoker; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Single; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; @@ -39,7 +40,15 @@ public class RequestBodyArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } @Test 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 83cc12edde..99de8173c3 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 @@ -18,6 +18,7 @@ package org.springframework.web.service.invoker; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.util.ObjectUtils; @@ -37,7 +38,15 @@ class RequestHeaderArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } // Base class functionality should be tested in NamedValueArgumentResolverTests. 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 f690316751..458c1f0f4a 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 @@ -16,6 +16,7 @@ package org.springframework.web.service.invoker; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.web.bind.annotation.RequestParam; @@ -39,7 +40,15 @@ public class RequestParamArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } // Base class functionality should be tested in NamedValueArgumentResolverTests. 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 ee5ba091ac..5089db6179 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 @@ -18,6 +18,7 @@ package org.springframework.web.service.invoker; import java.net.URI; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.web.service.annotation.GetExchange; @@ -34,7 +35,15 @@ public class UrlArgumentResolverTests { private final TestHttpClientAdapter client = new TestHttpClientAdapter(); - private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class); + private Service service; + + + @BeforeEach + void setUp() throws Exception { + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(this.client); + proxyFactory.afterPropertiesSet(); + this.service = proxyFactory.createClient(Service.class); + } @Test 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 93ee2d4af1..1de7120ca9 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 @@ -65,7 +65,7 @@ public class WebClientHttpServiceProxyTests { @Test - void greeting() { + void greeting() throws Exception { prepareResponse(response -> response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!")); @@ -77,7 +77,7 @@ public class WebClientHttpServiceProxyTests { } @Test - void greetingWithRequestAttribute() { + void greetingWithRequestAttribute() throws Exception { Map attributes = new HashMap<>(); @@ -100,14 +100,15 @@ public class WebClientHttpServiceProxyTests { assertThat(attributes).containsEntry("myAttribute", "myAttributeValue"); } - private TestHttpService initHttpService() { + private TestHttpService initHttpService() throws Exception { WebClient webClient = WebClient.builder().baseUrl(this.server.url("/").toString()).build(); return initHttpService(webClient); } - private TestHttpService initHttpService(WebClient webClient) { - WebClientAdapter clientAdapter = new WebClientAdapter(webClient); - HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(clientAdapter).build(); + private TestHttpService initHttpService(WebClient webClient) throws Exception { + WebClientAdapter client = new WebClientAdapter(webClient); + HttpServiceProxyFactory proxyFactory = new HttpServiceProxyFactory(client); + proxyFactory.afterPropertiesSet(); return proxyFactory.createClient(TestHttpService.class); }