Spring 3.1 M1: MVC Namespace Enhancements and @Configuration |
|

In this 5th post of the series describing Spring 3.1 M1 features, I will focus on web applications. In the first half I'll discuss enhancements to the MVC XML namespace. Then I'll show how to create the equivalent of the MVC namespace with all Java configuration. At the end I mention some of the Servlet 3.0 related configuration changes you can expect in 3.1 M2.
MVC Namespace Improvements
Spring MVC 3.0 provided a custom MVC namespace. The centerpiece of the namespace — the <mvc:annotation-driven> element, configured everything required to process requests with annotated controller methods. More importantly though it set up a range of defaults that go along with having to do with type conversion, formatting, validation, reading and writing of the body of requests and respones and so on.
Over time a number of you have requested to gain more control over various aspects the above mentioned default configuration and we've addressed a number of those requests in the 3.1 M1 release.
Registration of Formatters
We'll start with the registration of Converters and Formatters, which is done by supplying your own ConversionService instance as follows:
<mvc:annotation-driven conversion-service="..." />
For custom Formatters you would subclass FormattingConversionServiceFactoryBean and register the Formatters in code. Starting with 3.1 M1 you can register Formatter and AnnontationFormatterFactory types declaratively using a setter:
<mvc:annotation-driven conversion-service="conversionService" /> <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <list> <bean class="org.example.EmailFormatter"/> <bean class="org.example.PhoneAnnotationFormatterFactory"/> </list> </property> </bean>
You still have the option to register Converters and Formatters in code. This is done with the FormatterRegistrar interface introduced in this release. Here is an example:
public class FinancialInstrumentFormatterRegistry implements FormatterRegistrar {
public void registerFormatters(FormatterRegistry registry) {
// Register custom Converters and Formatters here...
}
}
And this is how your FormatterRegistrary can be plugged in:
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatterRegistrars"> <list> <bean class="org.example.FinancialInstrumentFormatterRegistrar"/> </list> </property> </bean>
So, when should you use a FormatterRegistrar as opposed to the formatters setter? A FormatterRegistrar is useful when you need to register multiple related converters and formatters for a specific formatting category from one place. Another case is registering a Formatter indexed under a field type other than its own generic type <T> or perhaps registering a Formatter from a Printer/Parser pair. A good example of an actual FormatterRegistrar implementation is the JodaTimeFormatterRegistrar in the Spring Framework so have a look in there.
One last option in the FormattingConversionServiceFactoryBean is the ability to turn off default Formatter registrations completely through the registerDefaultFormatters flag.
Registration of HttpMessageConverters
Starting with 3.1 M1 you can register HttpMessageConverters through a sub-element of mvc:annotation-driven. For example:
<mvc:annotation-driven> <mvc:message-converters> <bean class="com.google.protobuf.spring.http.ProtobufHttpMessageConverter"/> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="prefixJson" value="true"/> </bean> </mvc:message-converters> </mvc:annotation-driven>
The list of message converters provided this way take priority over the message converters the MVC namespace registers by default. For example, above we've added one custom converter, ProtobufHttpMessageConverter and we've also provided an instance of the Spring MVC's MappingJacksonHttpMessageConvert customized according to application needs.
If you don't want any message converters to be registered by default use the register-defaults attribute on the <mvc:message-converters> element.
Registration of custom WebArgumentResolvers
A WebArgumentResolver, if you've never seen one before, is used for resolving custom arguments in @RequestMapping methods. The Spring Mobile project has a SitePreferenceWebArgumentResolver. It resolves SitePreference method parameter types that indicate whether the user wants the mobile or the full version of a page. Starting with Spring 3.1 M1 you can register custom argument resolvers through the MVC namespace:
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="org.springframework.mobile.device.site.SitePreferenceWebArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven>
Custom MessageCodesResolver
Last in the list is the ability to provide a custom MessageCodesResolver:
<mvc:annotation-driven message-codes-resolver="messageCodesResolver" /> <bean id="messageCodesResolver" class="org.example.CustomMessageCodesResolver" />
There are lots of other things that could be done with the MVC namespace. The above list should help cover the most common use cases for added flexibility but do let us know if you think there are other important ones we've missed.
From XML to @Configuration
I this part of the post I'll take an existing sample application: the mvc-showcase that many of you may be familiar with from prior posts by Keith Donald and replace its XML configuration with Java-based configuration. Doing that allow to compare the code and configuration before and after.
The resulting sample application is available for checkout at spring-3.1-mvc-java-config. You can browse the source code directly on GitHub or follow the README instructions and get the code locally.
Our first step is to modify web.xml to point to our Java-based configuration and to specify the ApplicationContext type to use to process that configuration. Below is the relevant web.xml fragment:
<servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value> org.springframework.samples.mvc.config.MvcFeatures org.springframework.samples.mvc.config.MvcBeans </param-value> </init-param> </servlet>
Next we will create MvcFeatures and MvcBeans in the ~.config package. MvcFeatures contributes @Feature methods and is our main point of interest:
@FeatureConfiguration
class MvcFeatures {
@Feature
public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
return new MvcAnnotationDriven().conversionService(conversionService)
.argumentResolvers(new CustomArgumentResolver());
}
// ...
}
The above snippet is the equivalent of this XML namespace configuration:
<mvc:annotation-driven conversion-service="conversionService"> <mvc:argument-resolvers> <bean class="org.springframework.samples.mvc.data.custom.CustomArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven>
As you can see MvcAnnotationDriven provides the same options as the XML elements using a convenient chained method API. Also notice that we've declared a ConversionService method parameter. This parameter is auto-wired by type and injected. Its declaration can be found in MvcBeans:
@Configuration
public class MvcBeans {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService bean = new DefaultFormattingConversionService();
bean.addFormatterForFieldAnnotation(new MaskFormatAnnotationFormatterFactory());
return bean;
}
// ...
}
Note the use of the DefaultFormattingConversionService rather than the familiar FormattingConversionServiceFactoryBean typically used in XML configuration. This former gives us the same default Converter and Formatter registrations as the latter but is better suited for use with Java configuration — it provides a simple constructor instead of the FactoryBean lifecycle initialization methods invoked by Spring when using XML.
The remaining portion of MvcFeatures declares the equivalent of the the <mvc:resources>, <mvc:view-controller>, and the <context:component-scan> elements:
@FeatureConfiguration
class MvcFeatures {
// ...
@Feature
public MvcResources resources() {
return new MvcResources("/resources/**", "/resources/");
}
@Feature
public MvcViewControllers viewController() {
return new MvcViewControllers("/", "home");
}
@Feature
public ComponentScanSpec componentScan() {
return new ComponentScanSpec("org.springframework.samples").excludeFilters(
new AnnotationTypeFilter(Configuration.class),
new AnnotationTypeFilter(FeatureConfiguration.class));
}
}
There are two things worth noting. One is that a single instance of MvcViewControllers is needed to define any number of view controllers using chained method calls. The second is the use of an exclude filter in the componentScan() method in order to prevent MvcFeatures and MvcBeans from getting registered twice — once by the AnnotationConfigWebApplicationContext and a second time by the component scan.
For completeness this is the remaining part of MvcBeans:
@Configuration
public class MvcBeans {
// ...
@Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
return bean;
}
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
}
The last step is to remove the Spring XML configuration located under /WEB-INF/spring.
Summary
So there we are. We've bootstrapped a web application with all Java-based Spring configuration. Now that @FeatureConfiguration and @Feature have been introduced you can expect to see more and more FeatureSpecification implementations as an alternative to custom XML namespaces. I rather like the end result of the Java configuration but of course that doesn't mean my existing applications need to switch. It's all about having choice. If you prefer the declarative nature of XML and you use an IDE with code completion on class and method names in Spring XML configuration, then using XML namespaces is fine as well.
As heard recently in the webinar Introducing Spring Framework 3.1, in milestone 2 of Spring 3.1 you can expect to see Servlet 3.0 support including XML-free web application setup (i.e no web.xml) in combination with AnnotationConfigWebApplicationContext and the environment abstraction demonstrated in this and the previous posts of this blog series.
We hope you like these features and find them useful. Please let us know what you think.
Similar Posts
- Spring 3.1 M2: Spring MVC Enhancements
- Spring 3.1 M1: Introducing FeatureSpecification support
- Spring 3 Type Conversion and Validation
- More on Java Configuration
- Spring Framework 3.0 M3 released





Mark says:
Added on March 21st, 2011 at 4:49 amGood one. How come no has post a comment yet?
I like that we can now register custom converters and resolvers under the mvc:annotation-driven tag.
Kyuhyun Park says:
Added on March 25th, 2011 at 3:18 amThere are support for "mvc:interceptors" ?
Marcel Overdijk says:
Added on May 6th, 2011 at 8:34 amAnd for ?
Marcel Overdijk says:
Added on May 6th, 2011 at 8:34 amhmm that went wrong…
And for mvc:default-servlet-handler ?
Dilip says:
Added on June 23rd, 2011 at 6:53 amWhat about to use namespaces when I am using MappingJacksonHttpMessageConverter. Is MappingJacksonHttpMessageConverter supports namesapces IF yes then how to configure it
Dilip says:
Added on June 23rd, 2011 at 7:00 amI am using MappingJacksonHttpMessageConverter and need to support namesapces Is this possible if yes then how to configure it. any guidelines will help me
Casey Lucas says:
Added on August 17th, 2011 at 4:40 pmThanks for the tips about registering custom HttpMessageConverters. I was able to create and use a custom MessageConverter that uses Jerkson for rendering Scala objects. See http://blog.caseylucas.com/2011/08/17/jerkson-spring-scala/
Zakos says:
Added on September 12th, 2011 at 5:03 amAs I prefer using annotation as much as I can , there are things that doesn't seems right to use with annotation like ApplicationContext , which need to stays in xml imo.
Rossen Stoyanchev (blog author) says:
Added on September 12th, 2011 at 8:36 amZakos, please see the blog post for 3.1 M2 (if you hadn't already):
http://blog.springsource.com/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2/
The approach to Java based configuration for Spring MVC was revised in M2 to the effect that it no longer "mimics" the MVC XML namespace but rather takes a different approach, one that takes advantage of Java, provides more transparency and allows customizations that are not possible with the XML namespace.
Eduard says:
Added on November 5th, 2012 at 3:37 pmFor anyone still reading this blog post: it's mostly outdated. @Feature, @FeatureConfiguration, and FeatureSpecification don't exist in current 3.1.x releases. See the following blog post for more information: http://blog.springsource.org/2011/06/10/spring-3-1-m2-configuration-enhancements/
Rossen Stoyanchev (blog author) says:
Added on November 5th, 2012 at 4:38 pmThanks, Eduard! I added an update above to that extent. Please read this blog post instead:
http://blog.springsource.org/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2/