SPR-8234 Switch to strongly typed custom argument resolvers property
This commit is contained in:
parent
54bbcf3a42
commit
23e37b6842
|
|
@ -16,13 +16,20 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config;
|
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.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
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.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
import org.springframework.context.config.FeatureSpecification;
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.xml.DomUtils;
|
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;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -63,14 +70,15 @@ class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefi
|
||||||
}
|
}
|
||||||
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
|
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
|
||||||
if (resolversElement != null) {
|
if (resolversElement != null) {
|
||||||
spec.argumentResolvers(extractBeanSubElements(resolversElement, parserContext));
|
ManagedList<BeanDefinitionHolder> beanDefs = extractBeanSubElements(resolversElement, parserContext);
|
||||||
|
spec.argumentResolvers(wrapWebArgumentResolverBeanDefs(beanDefs));
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManagedList<? super Object> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
private ManagedList<BeanDefinitionHolder> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
||||||
ManagedList<? super Object> list = new ManagedList<Object>();
|
ManagedList<BeanDefinitionHolder> list = new ManagedList<BeanDefinitionHolder>();
|
||||||
list.setSource(parserContext.extractSource(parentElement));
|
list.setSource(parserContext.extractSource(parentElement));
|
||||||
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, "bean")) {
|
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, "bean")) {
|
||||||
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(beanElement);
|
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(beanElement);
|
||||||
|
|
@ -80,4 +88,23 @@ class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefi
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ManagedList<BeanDefinitionHolder> wrapWebArgumentResolverBeanDefs(List<BeanDefinitionHolder> beanDefs) {
|
||||||
|
ManagedList<BeanDefinitionHolder> result = new ManagedList<BeanDefinitionHolder>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.web.servlet.config;
|
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.parsing.ProblemCollector;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.context.config.AbstractFeatureSpecification;
|
import org.springframework.context.config.AbstractFeatureSpecification;
|
||||||
|
|
@ -145,8 +146,8 @@ public final class MvcAnnotationDriven extends AbstractFeatureSpecification {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void messageConverters(ManagedList<? super Object> messageConverters) {
|
void messageConverters(ManagedList<BeanDefinitionHolder> converterBeanDefinitions) {
|
||||||
this.messageConverters = messageConverters;
|
this.messageConverters.addAll(converterBeanDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagedList<?> messageConverters() {
|
ManagedList<?> messageConverters() {
|
||||||
|
|
@ -183,8 +184,8 @@ public final class MvcAnnotationDriven extends AbstractFeatureSpecification {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void argumentResolvers(ManagedList<? super Object> argumentResolvers) {
|
void argumentResolvers(ManagedList<BeanDefinitionHolder> resolverBeanDefinitions) {
|
||||||
this.argumentResolvers = argumentResolvers;
|
this.argumentResolvers.addAll(resolverBeanDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagedList<?> argumentResolvers() {
|
ManagedList<?> argumentResolvers() {
|
||||||
|
|
|
||||||
|
|
@ -175,28 +175,13 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
|
||||||
* Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and
|
* 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
|
* {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values
|
||||||
* ahead of the standard argument resolvers registered by default.
|
* ahead of the standard argument resolvers registered by default.
|
||||||
* <p>Argument resolvers of type {@link HandlerMethodArgumentResolver} and {@link WebArgumentResolver} are
|
* <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
|
||||||
* accepted with instances of the latter adapted via {@link ServletWebArgumentResolverAdapter}. For new
|
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
|
||||||
* implementations {@link HandlerMethodArgumentResolver} should be preferred over {@link WebArgumentResolver}.
|
|
||||||
*/
|
*/
|
||||||
public void setCustomArgumentResolvers(List<?> argumentResolvers) {
|
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
if (argumentResolvers == null) {
|
if (argumentResolvers != null) {
|
||||||
return;
|
this.customArgumentResolvers.addAll(argumentResolvers);
|
||||||
}
|
}
|
||||||
List<HandlerMethodArgumentResolver> adaptedResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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
|
* 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.
|
* are given a chance to resolve argument values ahead of the standard argument resolvers registered by default.
|
||||||
* <p>Argument resolvers of type {@link HandlerMethodArgumentResolver} and {@link WebArgumentResolver} are
|
* <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
|
||||||
* accepted with instances of the latter adapted via {@link ServletWebArgumentResolverAdapter}. For new
|
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
|
||||||
* implementations {@link HandlerMethodArgumentResolver} should be preferred over {@link WebArgumentResolver}.
|
|
||||||
*/
|
*/
|
||||||
public void setCustomArgumentResolvers(List<?> argumentResolvers) {
|
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
if (argumentResolvers == null) {
|
if (argumentResolvers != null) {
|
||||||
return;
|
this.customArgumentResolvers.addAll(argumentResolvers);
|
||||||
}
|
}
|
||||||
List<HandlerMethodArgumentResolver> adaptedResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.request.NativeWebRequest;
|
import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
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.multipart.support.StringMultipartFileEditor;
|
||||||
import org.springframework.web.servlet.DispatcherServlet;
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
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.ViewResolver;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
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.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
import org.springframework.web.util.NestedServletException;
|
import org.springframework.web.util.NestedServletException;
|
||||||
|
|
@ -570,7 +572,8 @@ public class ServletHandlerMethodTests {
|
||||||
wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class));
|
wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class));
|
||||||
RootBeanDefinition adapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class);
|
RootBeanDefinition adapterDef = new RootBeanDefinition(RequestMappingHandlerMethodAdapter.class);
|
||||||
adapterDef.getPropertyValues().add("webBindingInitializer", new MyWebBindingInitializer());
|
adapterDef.getPropertyValues().add("webBindingInitializer", new MyWebBindingInitializer());
|
||||||
WebArgumentResolver[] argumentResolvers = new WebArgumentResolver[] {new MySpecialArgumentResolver()};
|
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||||
|
argumentResolvers.add(new ServletWebArgumentResolverAdapter(new MySpecialArgumentResolver()));
|
||||||
adapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
|
adapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
|
||||||
wac.registerBeanDefinition("handlerAdapter", adapterDef);
|
wac.registerBeanDefinition("handlerAdapter", adapterDef);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue