From 23e37b68420f8ad4576b719ddba7ba42a6a6cc5c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 11 Apr 2011 15:50:04 +0000 Subject: [PATCH] SPR-8234 Switch to strongly typed custom argument resolvers property --- .../AnnotationDrivenBeanDefinitionParser.java | 33 +++++++++++++++++-- .../servlet/config/MvcAnnotationDriven.java | 9 ++--- .../RequestMappingHandlerMethodAdapter.java | 25 +++----------- ...MappingHandlerMethodExceptionResolver.java | 25 +++----------- .../annotation/ServletHandlerMethodTests.java | 5 ++- 5 files changed, 49 insertions(+), 48 deletions(-) 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 9df3b5e135c..ad4885a8453 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 @@ -16,13 +16,20 @@ package org.springframework.web.servlet.config; +import java.util.ArrayList; +import java.util.List; + import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser; import org.springframework.context.config.FeatureSpecification; +import org.springframework.util.ClassUtils; import org.springframework.util.xml.DomUtils; +import org.springframework.web.bind.support.WebArgumentResolver; +import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter; import org.w3c.dom.Element; /** @@ -63,14 +70,15 @@ class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefi } Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers"); if (resolversElement != null) { - spec.argumentResolvers(extractBeanSubElements(resolversElement, parserContext)); + ManagedList beanDefs = extractBeanSubElements(resolversElement, parserContext); + spec.argumentResolvers(wrapWebArgumentResolverBeanDefs(beanDefs)); } return spec; } - private ManagedList extractBeanSubElements(Element parentElement, ParserContext parserContext) { - ManagedList list = new ManagedList(); + private ManagedList extractBeanSubElements(Element parentElement, ParserContext parserContext) { + ManagedList list = new ManagedList(); list.setSource(parserContext.extractSource(parentElement)); for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, "bean")) { BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(beanElement); @@ -80,4 +88,23 @@ class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefi return list; } + private ManagedList wrapWebArgumentResolverBeanDefs(List beanDefs) { + ManagedList result = new ManagedList(); + + for (BeanDefinitionHolder beanDef : beanDefs) { + String className = beanDef.getBeanDefinition().getBeanClassName(); + Class clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader()); + + if (WebArgumentResolver.class.isAssignableFrom(clazz)) { + RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class); + adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef); + result.add(new BeanDefinitionHolder(adapter, beanDef.getBeanName() + "Adapter")); + } + else { + result.add(beanDef); + } + } + + return result; + } } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java index b28afea5556..641327df1ec 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcAnnotationDriven.java @@ -15,6 +15,7 @@ */ package org.springframework.web.servlet.config; +import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.parsing.ProblemCollector; import org.springframework.beans.factory.support.ManagedList; import org.springframework.context.config.AbstractFeatureSpecification; @@ -145,8 +146,8 @@ public final class MvcAnnotationDriven extends AbstractFeatureSpecification { return this; } - void messageConverters(ManagedList messageConverters) { - this.messageConverters = messageConverters; + void messageConverters(ManagedList converterBeanDefinitions) { + this.messageConverters.addAll(converterBeanDefinitions); } ManagedList messageConverters() { @@ -183,8 +184,8 @@ public final class MvcAnnotationDriven extends AbstractFeatureSpecification { return this; } - void argumentResolvers(ManagedList argumentResolvers) { - this.argumentResolvers = argumentResolvers; + void argumentResolvers(ManagedList resolverBeanDefinitions) { + this.argumentResolvers.addAll(resolverBeanDefinitions); } ManagedList argumentResolvers() { diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java index 88a77a95937..230bfec9f2e 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java @@ -175,28 +175,13 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda * Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and * {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values * ahead of the standard argument resolvers registered by default. - *

Argument resolvers of type {@link HandlerMethodArgumentResolver} and {@link WebArgumentResolver} are - * accepted with instances of the latter adapted via {@link ServletWebArgumentResolverAdapter}. For new - * implementations {@link HandlerMethodArgumentResolver} should be preferred over {@link WebArgumentResolver}. + *

An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter} + * or preferably converted to a {@link HandlerMethodArgumentResolver} instead. */ - public void setCustomArgumentResolvers(List argumentResolvers) { - if (argumentResolvers == null) { - return; + public void setCustomArgumentResolvers(List argumentResolvers) { + if (argumentResolvers != null) { + this.customArgumentResolvers.addAll(argumentResolvers); } - List adaptedResolvers = new ArrayList(); - for (Object resolver : argumentResolvers) { - if (resolver instanceof WebArgumentResolver) { - adaptedResolvers.add(new ServletWebArgumentResolverAdapter((WebArgumentResolver) resolver)); - } - else if (resolver instanceof HandlerMethodArgumentResolver) { - adaptedResolvers.add((HandlerMethodArgumentResolver) resolver); - } - else { - throw new IllegalArgumentException( - "An argument resolver must be a HandlerMethodArgumentResolver or a WebArgumentResolver"); - } - } - this.customArgumentResolvers.addAll(adaptedResolvers); } /** diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java index 31d5994212f..426760eb9f8 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java @@ -115,28 +115,13 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle /** * Set one or more custom argument resolvers to use with {@link ExceptionHandler} methods. Custom argument resolvers * are given a chance to resolve argument values ahead of the standard argument resolvers registered by default. - *

Argument resolvers of type {@link HandlerMethodArgumentResolver} and {@link WebArgumentResolver} are - * accepted with instances of the latter adapted via {@link ServletWebArgumentResolverAdapter}. For new - * implementations {@link HandlerMethodArgumentResolver} should be preferred over {@link WebArgumentResolver}. + *

An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter} + * or preferably converted to a {@link HandlerMethodArgumentResolver} instead. */ - public void setCustomArgumentResolvers(List argumentResolvers) { - if (argumentResolvers == null) { - return; + public void setCustomArgumentResolvers(List argumentResolvers) { + if (argumentResolvers != null) { + this.customArgumentResolvers.addAll(argumentResolvers); } - List adaptedResolvers = new ArrayList(); - for (Object resolver : argumentResolvers) { - if (resolver instanceof WebArgumentResolver) { - adaptedResolvers.add(new ServletWebArgumentResolverAdapter((WebArgumentResolver) resolver)); - } - else if (resolver instanceof HandlerMethodArgumentResolver) { - adaptedResolvers.add((HandlerMethodArgumentResolver) resolver); - } - else { - throw new IllegalArgumentException( - "An argument resolver must be a HandlerMethodArgumentResolver or a WebArgumentResolver"); - } - } - this.customArgumentResolvers.addAll(adaptedResolvers); } /** diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java index c8805fc8a09..7b661440947 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java @@ -122,6 +122,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.multipart.support.StringMultipartFileEditor; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.ModelAndView; @@ -129,6 +130,7 @@ import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver; import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver; +import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter; import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.util.NestedServletException; @@ -570,7 +572,8 @@ public class ServletHandlerMethodTests { wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); RootBeanDefinition adapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class); adapterDef.getPropertyValues().add("webBindingInitializer", new MyWebBindingInitializer()); - WebArgumentResolver[] argumentResolvers = new WebArgumentResolver[] {new MySpecialArgumentResolver()}; + List argumentResolvers = new ArrayList(); + argumentResolvers.add(new ServletWebArgumentResolverAdapter(new MySpecialArgumentResolver())); adapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers); wac.registerBeanDefinition("handlerAdapter", adapterDef); }