diff --git a/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurationSupport.java b/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurationSupport.java index 65b048d7..3861b800 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurationSupport.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurationSupport.java @@ -17,6 +17,7 @@ package org.springframework.ws.config.annotation; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import org.springframework.context.annotation.Bean; @@ -141,37 +142,38 @@ public class WsConfigurationSupport { * annotated endpoint methods. Consider overriding one of these other more * fine-grained methods: * */ @Bean public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() { - List argumentResolvers = new ArrayList<>(); + DefaultMethodEndpointAdapter adapter = DefaultMethodEndpointAdapter.withDefaults(); + LinkedList argumentResolvers = new LinkedList<>(adapter.getMethodArgumentResolvers()); addArgumentResolvers(argumentResolvers); + adapter.setMethodArgumentResolvers(argumentResolvers); - List returnValueHandlers = new ArrayList<>(); + LinkedList returnValueHandlers = new LinkedList<>( + adapter.getMethodReturnValueHandlers()); addReturnValueHandlers(returnValueHandlers); - - DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter(); - adapter.setCustomMethodArgumentResolvers(argumentResolvers); - adapter.setCustomMethodReturnValueHandlers(returnValueHandlers); + adapter.setMethodReturnValueHandlers(returnValueHandlers); return adapter; } /** - * Add custom {@link MethodArgumentResolver}s to use in addition to the ones + * Configure the {@link MethodArgumentResolver}s to use in addition to the ones * registered by default. - * @param argumentResolvers the list of custom converters; initially an empty list. + * @param argumentResolvers the list of resolvers; initially the default resolvers */ protected void addArgumentResolvers(List argumentResolvers) { } /** - * Add custom {@link MethodReturnValueHandler}s in addition to the ones registered by - * default. - * @param returnValueHandlers the list of custom handlers; initially an empty list. + * Configure the {@link MethodReturnValueHandler}s to use in addition to the ones + * registered by default. + * @param returnValueHandlers the list of handlers; initially the default handlers */ protected void addReturnValueHandlers(List returnValueHandlers) { } diff --git a/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurer.java b/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurer.java index dec311c5..28747729 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurer.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/config/annotation/WsConfigurer.java @@ -43,20 +43,18 @@ public interface WsConfigurer { } /** - * Add resolvers to support custom endpoint method argument types. - * @param argumentResolvers initially an empty list + * Configure the {@link MethodArgumentResolver}s to use in addition to the ones + * registered by default. + * @param argumentResolvers the list of resolvers; initially the default resolvers */ default void addArgumentResolvers(List argumentResolvers) { } /** - * Add handlers to support custom controller method return value types. - *

- * Using this option does not override the built-in support for handling return - * values. To customize the built-in support for handling return values, configure - * RequestMappingHandlerAdapter directly. - * @param returnValueHandlers initially an empty list + * Configure the {@link MethodReturnValueHandler}s to use in addition to the ones + * registered by default. + * @param returnValueHandlers the list of handlers; initially the default handlers */ default void addReturnValueHandlers(List returnValueHandlers) { diff --git a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/adapter/DefaultMethodEndpointAdapter.java b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/adapter/DefaultMethodEndpointAdapter.java index 0e8ae148..00c53cba 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/adapter/DefaultMethodEndpointAdapter.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/server/endpoint/adapter/DefaultMethodEndpointAdapter.java @@ -76,6 +76,16 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter private ClassLoader classLoader; + /** + * Create a new instance with default method argument and return value resolvers. + * @return a new instance with defaults configured + */ + public static DefaultMethodEndpointAdapter withDefaults() { + DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter(); + adapter.initDefaultStrategies(); + return adapter; + } + /** * Returns the list of {@code MethodArgumentResolver}s to use. */ @@ -92,7 +102,9 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter /** * Returns the custom argument resolvers. + * @deprecated as of 4.1.0 with no replacement */ + @Deprecated(since = "4.1.0", forRemoval = true) public List getCustomMethodArgumentResolvers() { return this.customMethodArgumentResolvers; } @@ -101,7 +113,10 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter * Sets the custom handlers for method arguments. Custom handlers are ordered after * built-in ones. To override the built-in support for return value handling use * {@link #setMethodArgumentResolvers(List)}. + * @deprecated as of 4.1.0 in favor of setting a single list + * @see #withDefaults() */ + @Deprecated(since = "4.1.0", forRemoval = true) public void setCustomMethodArgumentResolvers(List customMethodArgumentResolvers) { this.customMethodArgumentResolvers = customMethodArgumentResolvers; } @@ -122,7 +137,9 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter /** * Returns the custom return value handlers. + * @deprecated as of 4.1.0 with no replacement */ + @Deprecated(since = "4.1.0", forRemoval = true) public List getCustomMethodReturnValueHandlers() { return this.customMethodReturnValueHandlers; } @@ -131,7 +148,10 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter * Sets the handlers for custom return value types. Custom handlers are ordered after * built-in ones. To override the built-in support for return value handling use * {@link #setMethodReturnValueHandlers(List)}. + * @deprecated as of 4.1.0 in favor of setting a single list + * @see #withDefaults() */ + @Deprecated(since = "4.1.0", forRemoval = true) public void setCustomMethodReturnValueHandlers(List customMethodReturnValueHandlers) { this.customMethodReturnValueHandlers = customMethodReturnValueHandlers; } diff --git a/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurationSupportTest.java b/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurationSupportTest.java index 3e3547e4..ffd88095 100644 --- a/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurationSupportTest.java +++ b/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurationSupportTest.java @@ -18,82 +18,136 @@ package org.springframework.ws.config.annotation; import java.util.List; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.ws.config.annotation.WsConfigurationSupportTest.CustomArgumentResolverConfig.MyArgumentResolver; +import org.springframework.ws.config.annotation.WsConfigurationSupportTest.CustomDefaultMethodEndpointAdapterConfig.MyDefaultMethodEndpointAdapter; +import org.springframework.ws.config.annotation.WsConfigurationSupportTest.CustomInterceptorConfig.MyInterceptor; +import org.springframework.ws.config.annotation.WsConfigurationSupportTest.CustomReturnValueHandlerConfig.MyReturnValueHandler; import org.springframework.ws.server.EndpointInterceptor; import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter; +import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver; +import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler; +import org.springframework.ws.server.endpoint.adapter.method.SourcePayloadMethodProcessor; import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter; import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping; import static org.assertj.core.api.Assertions.assertThat; /** + * Tests for {@link WsConfigurationSupport}. + * * @author Arjen Poutsma + * @author Stephane Nicoll */ -public class WsConfigurationSupportTest { +class WsConfigurationSupportTest { - private ApplicationContext applicationContext; + @Test + void interceptors() { + try (ConfigurableApplicationContext applicationContext = load(CustomInterceptorConfig.class)) { + PayloadRootAnnotationMethodEndpointMapping endpointMapping = applicationContext + .getBean(PayloadRootAnnotationMethodEndpointMapping.class); + assertThat(endpointMapping.getOrder()).isEqualTo(0); + EndpointInterceptor[] interceptors = endpointMapping.getInterceptors(); + assertThat(interceptors).singleElement().isInstanceOf(MyInterceptor.class); + } + } - @BeforeEach - public void setUp() { + @Test + void argumentResolvers() { + try (ConfigurableApplicationContext applicationContext = load(CustomArgumentResolverConfig.class)) { + DefaultMethodEndpointAdapter bean = applicationContext.getBean(DefaultMethodEndpointAdapter.class); + List methodArgumentResolvers = bean.getMethodArgumentResolvers(); + assertThat(methodArgumentResolvers).hasSizeGreaterThan(1).element(0).isInstanceOf(MyArgumentResolver.class); + } + } + @Test + void returnValueHandlers() { + try (ConfigurableApplicationContext applicationContext = load(CustomReturnValueHandlerConfig.class)) { + DefaultMethodEndpointAdapter bean = applicationContext.getBean(DefaultMethodEndpointAdapter.class); + List methodReturnValueHandlers = bean.getMethodReturnValueHandlers(); + assertThat(methodReturnValueHandlers).hasSizeGreaterThan(1) + .element(0) + .isInstanceOf(MyReturnValueHandler.class); + } + } + + @Test + void defaultMethodEndpointAdapter() { + try (ConfigurableApplicationContext applicationContext = load(CustomDefaultMethodEndpointAdapterConfig.class)) { + assertThat(applicationContext.getBean(DefaultMethodEndpointAdapter.class)) + .isInstanceOf(MyDefaultMethodEndpointAdapter.class); + } + } + + private ConfigurableApplicationContext load(Class... componentClasses) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); - applicationContext.register(TestConfig.class); + applicationContext.register(componentClasses); applicationContext.refresh(); - - this.applicationContext = applicationContext; + return applicationContext; } - @Test - public void interceptors() { - - PayloadRootAnnotationMethodEndpointMapping endpointMapping = this.applicationContext - .getBean(PayloadRootAnnotationMethodEndpointMapping.class); - - assertThat(endpointMapping.getOrder()).isEqualTo(0); - - EndpointInterceptor[] interceptors = endpointMapping.getInterceptors(); - - assertThat(interceptors).hasSize(1); - assertThat(interceptors[0]).isInstanceOf(MyInterceptor.class); - } - - @Test - public void defaultMethodEndpointAdapter() { - - DefaultMethodEndpointAdapter endpointAdapter = this.applicationContext - .getBean(DefaultMethodEndpointAdapter.class); - - assertThat(endpointAdapter).isNotNull(); - assertThat(endpointAdapter).isInstanceOf(MyDefaultMethodEndpointAdapter.class); - } - - @Configuration - public static class TestConfig extends WsConfigurationSupport { + @Configuration(proxyBeanMethods = false) + static class CustomInterceptorConfig extends WsConfigurationSupport { @Override protected void addInterceptors(List interceptors) { interceptors.add(new MyInterceptor()); } + static class MyInterceptor extends EndpointInterceptorAdapter { + + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomArgumentResolverConfig extends WsConfigurationSupport { + + @Override + protected void addArgumentResolvers(List argumentResolvers) { + assertThat(argumentResolvers).isNotEmpty(); + argumentResolvers.add(0, new MyArgumentResolver()); + } + + static class MyArgumentResolver extends SourcePayloadMethodProcessor { + + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomReturnValueHandlerConfig extends WsConfigurationSupport { + + @Override + protected void addReturnValueHandlers(List returnValueHandlers) { + assertThat(returnValueHandlers).isNotEmpty(); + returnValueHandlers.add(0, new MyReturnValueHandler()); + } + + static class MyReturnValueHandler extends SourcePayloadMethodProcessor { + + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomDefaultMethodEndpointAdapterConfig extends WsConfigurationSupport { + @Bean @Override public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() { return new MyDefaultMethodEndpointAdapter(); } - } + static class MyDefaultMethodEndpointAdapter extends DefaultMethodEndpointAdapter { - public static class MyInterceptor extends EndpointInterceptorAdapter { - - } - - public static class MyDefaultMethodEndpointAdapter extends DefaultMethodEndpointAdapter { + } } diff --git a/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurerAdapterTest.java b/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurerAdapterTest.java index fb8e0816..9b10c4ea 100644 --- a/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurerAdapterTest.java +++ b/spring-ws-core/src/test/java/org/springframework/ws/config/annotation/WsConfigurerAdapterTest.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Arjen Poutsma */ +@Deprecated public class WsConfigurerAdapterTest { private ApplicationContext applicationContext; @@ -72,9 +73,9 @@ public class WsConfigurerAdapterTest { DefaultMethodEndpointAdapter endpointAdapter = this.applicationContext .getBean(DefaultMethodEndpointAdapter.class); - List argumentResolvers = endpointAdapter.getCustomMethodArgumentResolvers(); + List argumentResolvers = endpointAdapter.getMethodArgumentResolvers(); - assertThat(argumentResolvers).hasSize(1); + assertThat(argumentResolvers).hasSizeGreaterThan(1); assertThat(argumentResolvers.get(0)).isInstanceOf(MyMethodArgumentResolver.class); argumentResolvers = endpointAdapter.getMethodArgumentResolvers(); @@ -88,9 +89,9 @@ public class WsConfigurerAdapterTest { DefaultMethodEndpointAdapter endpointAdapter = this.applicationContext .getBean(DefaultMethodEndpointAdapter.class); - List returnValueHandlers = endpointAdapter.getCustomMethodReturnValueHandlers(); + List returnValueHandlers = endpointAdapter.getMethodReturnValueHandlers(); - assertThat(returnValueHandlers).hasSize(1); + assertThat(returnValueHandlers).hasSizeGreaterThan(1); assertThat(returnValueHandlers.get(0)).isInstanceOf(MyReturnValueHandler.class); returnValueHandlers = endpointAdapter.getMethodReturnValueHandlers(); @@ -109,12 +110,12 @@ public class WsConfigurerAdapterTest { @Override public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(new MyMethodArgumentResolver()); + argumentResolvers.add(0, new MyMethodArgumentResolver()); } @Override public void addReturnValueHandlers(List returnValueHandlers) { - returnValueHandlers.add(new MyReturnValueHandler()); + returnValueHandlers.add(0, new MyReturnValueHandler()); } }