Support <ref> for arg resolvers return value handlers
Issue: SPR-11927
This commit is contained in:
parent
0d5c5a3d33
commit
fa33ed4b4b
|
@ -471,21 +471,34 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
|||
private ManagedList<?> getArgumentResolvers(Element element, ParserContext parserContext) {
|
||||
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
|
||||
if (resolversElement != null) {
|
||||
ManagedList<BeanDefinitionHolder> argumentResolvers = extractBeanSubElements(resolversElement, parserContext);
|
||||
ManagedList<BeanMetadataElement> customAndReferencedResolvers = new ManagedList<BeanMetadataElement>();
|
||||
customAndReferencedResolvers.addAll(wrapWebArgumentResolverBeanDefs(argumentResolvers, parserContext));
|
||||
customAndReferencedResolvers.addAll(extractBeanRefSubElements(resolversElement, parserContext));
|
||||
return customAndReferencedResolvers;
|
||||
ManagedList<Object> resolvers = extractBeanSubElements(resolversElement, parserContext);
|
||||
return wrapLegacyResolvers(resolvers, parserContext);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ManagedList<?> getReturnValueHandlers(Element element, ParserContext parserContext) {
|
||||
Element handlersElement = DomUtils.getChildElementByTagName(element, "return-value-handlers");
|
||||
if (handlersElement != null) {
|
||||
return extractBeanSubElements(handlersElement, parserContext);
|
||||
private ManagedList<Object> wrapLegacyResolvers(List<Object> list, ParserContext context) {
|
||||
ManagedList<Object> result = new ManagedList<Object>();
|
||||
for (Object object : list) {
|
||||
if (object instanceof BeanDefinitionHolder) {
|
||||
BeanDefinitionHolder beanDef = (BeanDefinitionHolder) object;
|
||||
String className = beanDef.getBeanDefinition().getBeanClassName();
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, context.getReaderContext().getBeanClassLoader());
|
||||
if (WebArgumentResolver.class.isAssignableFrom(clazz)) {
|
||||
RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class);
|
||||
adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef);
|
||||
result.add(new BeanDefinitionHolder(adapter, beanDef.getBeanName() + "Adapter"));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result.add(object);
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private ManagedList<?> getReturnValueHandlers(Element element, ParserContext parserContext) {
|
||||
Element handlers = DomUtils.getChildElementByTagName(element, "return-value-handlers");
|
||||
return (handlers != null ? extractBeanSubElements(handlers, parserContext) : null);
|
||||
}
|
||||
|
||||
private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext parserContext) {
|
||||
|
@ -536,13 +549,12 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
|||
}
|
||||
|
||||
|
||||
private ManagedList<BeanDefinitionHolder> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
||||
ManagedList<BeanDefinitionHolder> list = new ManagedList<BeanDefinitionHolder>();
|
||||
private ManagedList<Object> extractBeanSubElements(Element parentElement, ParserContext parserContext) {
|
||||
ManagedList<Object> list = new ManagedList<Object>();
|
||||
list.setSource(parserContext.extractSource(parentElement));
|
||||
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, "bean")) {
|
||||
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(beanElement);
|
||||
beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(beanElement, beanDef);
|
||||
list.add(beanDef);
|
||||
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, "bean", "ref")) {
|
||||
Object object = parserContext.getDelegate().parsePropertySubElement(beanElement, null);
|
||||
list.add(object);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -566,25 +578,6 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
|||
return list;
|
||||
}
|
||||
|
||||
private ManagedList<BeanDefinitionHolder> wrapWebArgumentResolverBeanDefs(
|
||||
List<BeanDefinitionHolder> beanDefs, ParserContext parserContext) {
|
||||
|
||||
ManagedList<BeanDefinitionHolder> result = new ManagedList<BeanDefinitionHolder>();
|
||||
for (BeanDefinitionHolder beanDef : beanDefs) {
|
||||
String className = beanDef.getBeanDefinition().getBeanClassName();
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, parserContext.getReaderContext().getBeanClassLoader());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A FactoryBean for a CompositeUriComponentsContributor that obtains the
|
||||
|
|
|
@ -138,8 +138,7 @@
|
|||
<xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a HandlerMethodArgumentResolver bean definition. Expects a HandlerMethodArgumentResolver instance,
|
||||
WebArgumentResolver instances has to be wrapped with a ServletWebArgumentResolverAdapter
|
||||
A reference to a HandlerMethodArgumentResolver bean definition.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
|
@ -160,15 +159,27 @@
|
|||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element ref="beans:bean" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The HandlerMethodReturnValueHandler bean definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a HandlerMethodReturnValueHandler bean definition.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="java:org.springframework.web.method.support.HandlerMethodReturnValueHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="async-support" minOccurs="0">
|
||||
|
|
|
@ -117,26 +117,13 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
|||
assertNotNull(value);
|
||||
assertTrue(value instanceof List);
|
||||
List<HandlerMethodArgumentResolver> resolvers = (List<HandlerMethodArgumentResolver>) value;
|
||||
assertEquals(2, resolvers.size());
|
||||
assertEquals(3, resolvers.size());
|
||||
assertTrue(resolvers.get(0) instanceof ServletWebArgumentResolverAdapter);
|
||||
assertTrue(resolvers.get(1) instanceof TestHandlerMethodArgumentResolver);
|
||||
assertTrue(resolvers.get(2) instanceof TestHandlerMethodArgumentResolver);
|
||||
assertNotSame(resolvers.get(1), resolvers.get(2));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testArgumentResolversWithReference() {
|
||||
loadBeanDefinitions("mvc-config-argument-resolvers-references.xml");
|
||||
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
|
||||
assertNotNull(adapter);
|
||||
Object value = new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
|
||||
assertNotNull(value);
|
||||
assertTrue(value instanceof List);
|
||||
List<HandlerMethodArgumentResolver> resolvers = (List<HandlerMethodArgumentResolver>) value;
|
||||
assertEquals(2, resolvers.size());
|
||||
assertTrue(resolvers.get(0) instanceof ServletWebArgumentResolverAdapter);
|
||||
assertTrue(resolvers.get(1) instanceof TestHandlerMethodArgumentResolver);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testReturnValueHandlers() {
|
||||
|
@ -147,8 +134,10 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
|||
assertNotNull(value);
|
||||
assertTrue(value instanceof List);
|
||||
List<HandlerMethodReturnValueHandler> handlers = (List<HandlerMethodReturnValueHandler>) value;
|
||||
assertEquals(1, handlers.size());
|
||||
assertEquals(2, handlers.size());
|
||||
assertEquals(TestHandlerMethodReturnValueHandler.class, handlers.get(0).getClass());
|
||||
assertEquals(TestHandlerMethodReturnValueHandler.class, handlers.get(1).getClass());
|
||||
assertNotSame(handlers.get(0), handlers.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<mvc:annotation-driven>
|
||||
<mvc:argument-resolvers>
|
||||
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
|
||||
<ref bean="customArgumentResolver" />
|
||||
</mvc:argument-resolvers>
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<bean id="customArgumentResolver" class="org.springframework.web.servlet.config.TestHandlerMethodArgumentResolver"/>
|
||||
|
||||
</beans>
|
|
@ -9,7 +9,10 @@
|
|||
<mvc:argument-resolvers>
|
||||
<bean class="org.springframework.web.servlet.config.TestWebArgumentResolver"/>
|
||||
<bean class="org.springframework.web.servlet.config.TestHandlerMethodArgumentResolver"/>
|
||||
<ref bean="customArgumentResolver" />
|
||||
</mvc:argument-resolvers>
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<bean id="customArgumentResolver" class="org.springframework.web.servlet.config.TestHandlerMethodArgumentResolver"/>
|
||||
|
||||
</beans>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
@ -8,7 +8,10 @@
|
|||
<mvc:annotation-driven>
|
||||
<mvc:return-value-handlers>
|
||||
<bean class="org.springframework.web.servlet.config.TestHandlerMethodReturnValueHandler"/>
|
||||
<ref bean="customHandler" />
|
||||
</mvc:return-value-handlers>
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<bean id="customHandler" class="org.springframework.web.servlet.config.TestHandlerMethodReturnValueHandler"/>
|
||||
|
||||
</beans>
|
||||
|
|
Loading…
Reference in New Issue