Add order attribute to MVC ViewResolver config

The ViewResolverComposite that contains the ViewResolver's registered
throug the MVC Java config and namespace can now be assigned an
explicit order.
This commit is contained in:
Rossen Stoyanchev 2014-09-30 10:36:39 -04:00
parent 3b1d3257d5
commit 77bbfb6e7e
6 changed files with 84 additions and 3 deletions

View File

@ -133,7 +133,6 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser {
beanDef.getPropertyValues().add("viewResolvers", resolvers);
ManagedList<Object> list = new ManagedList<Object>(1);
list.add(beanDef);
compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list);
}
@ -141,6 +140,10 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser {
throw new IllegalArgumentException("Only one <content-negotiation> element is allowed.");
}
if (element.hasAttribute("order")) {
compositeResolverBeanDef.getPropertyValues().add("order", element.getAttribute("order"));
}
context.getReaderContext().getRegistry().registerBeanDefinition(beanName, compositeResolverBeanDef);
context.registerComponent(new BeanComponentDefinition(compositeResolverBeanDef, beanName));
context.popAndRegisterContainingComponent();

View File

@ -57,7 +57,7 @@ public class ViewResolverRegistry {
private final List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>(4);
private int order = Ordered.LOWEST_PRECEDENCE;
private Integer order;
private ContentNegotiationManager contentNegotiationManager;
@ -112,7 +112,7 @@ public class ViewResolverRegistry {
private void initContentNegotiatingViewResolver(View[] defaultViews) {
// ContentNegotiatingResolver in the registry: elevate its precedence!
this.order = Ordered.HIGHEST_PRECEDENCE;
this.order = (this.order == null ? Ordered.HIGHEST_PRECEDENCE : this.order);
if (this.contentNegotiatingResolver != null) {
if (!ObjectUtils.isEmpty(defaultViews)) {
@ -257,6 +257,22 @@ public class ViewResolverRegistry {
this.viewResolvers.add(viewResolver);
}
/**
* ViewResolver's registered through this registry are encapsulated in an
* instance of {@link org.springframework.web.servlet.view.ViewResolverComposite
* ViewResolverComposite} and follow the order of registration.
* This property determines the order of the ViewResolverComposite itself
* relative to any additional ViewResolver's (not registered here) present in
* the Spring configuration
* <p>By default this property is not set, which means the resolver is ordered
* at {@link Ordered#LOWEST_PRECEDENCE} unless content negotiation is enabled
* in which case the order (if not set explicitly) is changed to
* {@link Ordered#HIGHEST_PRECEDENCE}.
*/
public void order(int order) {
this.order = order;
}
protected boolean hasBeanOfType(Class<?> beanType) {
return !ObjectUtils.isEmpty(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.applicationContext, beanType, false, false));

View File

@ -949,6 +949,20 @@
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:attribute name="order" type="xsd:int">
<xsd:annotation>
<xsd:documentation><![CDATA[
ViewResolver's registered through this element are encapsulated in an
instance of org.springframework.web.servlet.view.ViewResolverComposite and
follow the order of registration. This attribute determines the order of the
ViewResolverComposite itself relative to any additional ViewResolver's
(not registered through this element) present in the Spring configuration
By default this property is not set, which means the resolver is ordered at
Ordered.LOWEST_PRECEDENCE unless content negotiation is enabled in which case
the order (if not set explicitly) is changed to Ordered.HIGHEST_PRECEDENCE.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>

View File

@ -767,6 +767,16 @@ public class MvcNamespaceTests {
assertSame(manager, this.appContext.getBean(ContentNegotiationManager.class));
}
@Test
public void testViewResolutionWithOrderSet() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution-custom-order.xml", 1);
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
assertEquals("Actual: " + compositeResolver.getViewResolvers(), 1, compositeResolver.getViewResolvers().size());
assertEquals(123, compositeResolver.getOrder());
}
@Test
public void testPathMatchingHandlerMappings() throws Exception {
loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 22);

View File

@ -246,6 +246,20 @@ public class WebMvcConfigurationSupportTests {
assertNull(resolver.resolveViewName("anyViewName", Locale.ENGLISH));
}
@Test
public void mvcViewResolverWithOrderSet() {
ApplicationContext context = initContext(CustomViewResolverOrderConfig.class);
ViewResolverComposite resolver = context.getBean("mvcViewResolver", ViewResolverComposite.class);
Map<String, ViewResolver> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, ViewResolver.class, true, false);
assertNotNull(resolver);
assertEquals(1, resolver.getViewResolvers().size());
assertEquals(InternalResourceViewResolver.class, resolver.getViewResolvers().get(0).getClass());
assertEquals(123, resolver.getOrder());
}
@Test
public void defaultPathMatchConfiguration() throws Exception {
ApplicationContext context = initContext(WebConfig.class);
@ -286,6 +300,16 @@ public class WebMvcConfigurationSupportTests {
}
}
@EnableWebMvc
@Configuration
public static class CustomViewResolverOrderConfig extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp();
registry.order(123);
}
}
@Controller
public static class TestController {

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:view-resolvers order="123">
<mvc:bean-name />
</mvc:view-resolvers>
</beans>