To externalize data binding initialization, you can provide a custom implementation of theEncouraged by this citation I registered my own bean along the usual <mvc:annotation-driven />WebBindingInitializer
interface, which you then enable by supplying a custom bean configuration for anAnnotationMethodHandlerAdapter
, thus overriding the default configuration.
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer" ref="MyWebBindingInitializer" />
</bean>
<bean class="[...].DefultWebBindingInitializer" id="MyWebBindingInitializer" />
At this point I've encountered first problem - the order of beans registration matters in the above case - first registered handler will be used. This is reasonable, one AnnotationMethodHandlerAdapter is registered by Spring while processing <mvc:annotation-driven /> and one by me. First registered wins :)I've moved my bean before <mvc:annotation-driven /> and started enjoying its work. After few days I was preparing some functionality returning one value from the handler method, which should be converted automagically to JSON response (see my posts: JSON - Jackson to the rescue and JSON - Jackson Serialization Narrowed). To my surprise, usual configuration didn't worked, I started digging through my own and Spring Framework code, and found the reason (which in fact can be also deduced from mvc:annotation-driven documentation) - my own bean didn't registered the same message converters as parser responsible for processing mvc:annotation-driven (AnnotationDrivenBeanDefinitionParser) and especially one needed by me: MappingJacksonHttpMessageConverter.
At this point I had few possibilities to solve this problem, I could for example register appropriate message converter myself, but I decided to go a different way, because solving the problems generated ourselves, is worse than avoiding those problems :)
I've prepared BeanPostProcessor implementation correcting the one property required by me:
public class MVCConfigurationPostProcessor implements BeanPostProcessor {
private WebBindingInitializer webBindingInitializer;
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AnnotationMethodHandlerAdapter) {
((AnnotationMethodHandlerAdapter) bean).setWebBindingInitializer(webBindingInitializer);
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public void setWebBindingInitializer(WebBindingInitializer webBindingInitializer) {
this.webBindingInitializer = webBindingInitializer;
}
}
Then I've corrected my Spring configuration to:<bean class="[...].MVCConfigurationPostProcessor">
<property name="webBindingInitializer" ref="MyWebBindingInitializer" />
</bean>
<bean id="MyWebBindingInitializer" class="[...].DefultWebBindingInitializer" />
<mvc:annotation-driven />
Finally I was able to enjoy both AnnotationMethodHandlerAdapter using my own WebBindingInitializer and JSON conversion working correctly :).