diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 226b67b7af..9965b8c9e1 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -119,12 +119,16 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver); ManagedList messageConverters = getMessageConverters(element, source, parserContext); + ManagedList argumentResolvers = getArgumentResolvers(element, source, parserContext); RootBeanDefinition annAdapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); annAdapterDef.setSource(source); annAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); annAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef); annAdapterDef.getPropertyValues().add("messageConverters", messageConverters); + if (argumentResolvers != null) { + annAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers); + } String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef); RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class); @@ -211,6 +215,21 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { } } + private ManagedList getArgumentResolvers(Element element, Object source, ParserContext parserContext) { + Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers"); + if (resolversElement != null) { + ManagedList argumentResolvers = new ManagedList(); + argumentResolvers.setSource(source); + for (Element resolver : DomUtils.getChildElementsByTagName(resolversElement, "bean")) { + BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(resolver); + beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(resolver, beanDef); + argumentResolvers.add(beanDef); + } + return argumentResolvers; + } + return null; + } + private ManagedList getMessageConverters(Element element, Object source, ParserContext parserContext) { Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters"); if (convertersElement != null) { diff --git a/org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.1.xsd b/org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.1.xsd index e62fb75a89..4405606bc1 100644 --- a/org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.1.xsd +++ b/org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.1.xsd @@ -31,6 +31,27 @@ + + + + + + + + + + + + + + diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java index 04a57ae43e..8aba05e6de 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java @@ -23,12 +23,15 @@ import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.MethodParameter; import org.springframework.core.io.ClassPathResource; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.ResourceHttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.validation.MessageCodesResolver; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; +import org.springframework.web.bind.support.WebArgumentResolver; +import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver; @@ -67,6 +70,17 @@ public class AnnotationDrivenBeanDefinitionParserTests { verifyMessageConverters(appContext.getBean(AnnotationMethodHandlerExceptionResolver.class)); } + @Test + public void testArgumentResolvers() { + AnnotationMethodHandlerAdapter adapter = appContext.getBean(AnnotationMethodHandlerAdapter.class); + assertNotNull(adapter); + Object resolvers = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers"); + assertNotNull(resolvers); + assertTrue(resolvers instanceof WebArgumentResolver[]); + assertEquals(2, ((WebArgumentResolver[]) resolvers).length); + assertTrue(((WebArgumentResolver[]) resolvers)[0] instanceof TestWebArgumentResolver); + assertTrue(((WebArgumentResolver[]) resolvers)[1] instanceof TestWebArgumentResolver); + } private void verifyMessageConverters(Object bean) { assertNotNull(bean); @@ -78,17 +92,25 @@ public class AnnotationDrivenBeanDefinitionParserTests { assertTrue(((HttpMessageConverter[]) converters)[1] instanceof ResourceHttpMessageConverter); } - private static class TestMessageCodesResolver implements MessageCodesResolver { +} - public String[] resolveMessageCodes(String errorCode, String objectName) { - throw new IllegalStateException("Not expected to be invoked"); - } +class TestWebArgumentResolver implements WebArgumentResolver { - @SuppressWarnings("rawtypes") - public String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) { - throw new IllegalStateException("Not expected to be invoked"); - } + public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception { + return null; + } + +} + +class TestMessageCodesResolver implements MessageCodesResolver { + + public String[] resolveMessageCodes(String errorCode, String objectName) { + return new String[] { "test.foo.bar" }; + } + @SuppressWarnings("rawtypes") + public String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) { + return new String[] { "test.foo.bar" }; } } diff --git a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-annotation-driven.xml b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-annotation-driven.xml index 6a6d09fc61..8350a079fd 100644 --- a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-annotation-driven.xml +++ b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-annotation-driven.xml @@ -6,13 +6,16 @@ http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> + + + + - +