Affects: 5.3.29 (most likely current as well)
In the documentation for Interceptors in Spring MVC the methods for adding them via WebMvcConfigurer.addInterceptors(InterceptorRegistry) and <mvc:interceptors/> (in XML) are presented as equivalent, which is not strictly true.
Interceptors registered via <mvc:interceptors/> are added as MappedInterceptors to the ApplicationContext to be later picked up by AbstractHandlerMapping.detectMappedInterceptors(List<HandlerInterceptor>) (via initApplicationContext()) and added to the list of Interceptors.
Interceptors configured via WebMvcConfigurer.addInterceptors() (or WebMvcConfigurationSupport) will be directly set as Interceptors via a call to AbstractHandlerMapping.setInterceptors() (in requestMappingHandlerMapping()).
As a result, FlowHandlerMapping (and possibly others) will be aware of Interceptors if these are configured via XML, but not via recommended Java Config.
As far as I understand it, there is one workaround and the possibility to make the configuration explicit.
Workaround
Instead of adding the Interceptor in addInterceptors(), a bean of type MappedInterceptor is defined in the configuration class:
@Bean
public MappedInterceptor openSessionInViewInterceptor(SessionFactory sessionFactory) {
OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
interceptor.setSessionFactory(sessionFactory);
return new MappedInterceptor(null, interceptor);
}
That way the Interceptor gets picked up the same way as being configured via <mvc:interceptors/> (while not being obvious).
Explicit configuration
The Interceptor is configured as bean, added in addInterceptors() and available for usage in other handlers (in this example Spring Web Flows FlowHandlerMapping).
@Autowired private SessionFactory sessionFactory;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addWebRequestInterceptor(openSessionInViewInterceptor());
}
@Bean
public OpenSessionInViewInterceptor openSessionInViewInterceptor() {
OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
interceptor.setSessionFactory(sessionFactory);
return interceptor;
}
@Bean
public FlowHandlerMapping flowMappings() {
FlowHandlerMapping mapping = new FlowHandlerMapping();
// [..]
mapping.setInterceptors(openSessionInViewInterceptor());
return mapping;
}
Proposed Solution
To document this difference in behavior, I would propose another "Note" in the documentation. Something like:
Note: Interceptors configured via <mvc:interceptors/> will be internally wrapped as MappedInterceptors and picked up on initialization. That way all HandlerMappings – even those not from Spring MVC, especially Spring Web Flows FlowHandlerMapping – will configured with those Interceptors.
If you are using Java Configuration you will have to make the Interceptor available as Bean to be explicitly set while configuring other relevant HandlerMappings.
Wishlist
I am aware of the falling out of favor of the "Open Session in View" pattern and prevalent usage of other web technologies not depending on server rendering and therefore Spring Web Flow. At the same time, I think there are many applications out there using these technologies and pattern. Therefore I would appreciate it, if you could use OpenSessionInViewInterceptor as example in your documentation (perhaps even mentioning FlowHandlerMapping) to make it web searchable and obvious, that there is something to consider while switching from XML to Java Config
Affects: 5.3.29 (most likely current as well)
In the documentation for Interceptors in Spring MVC the methods for adding them via
WebMvcConfigurer.addInterceptors(InterceptorRegistry)and<mvc:interceptors/>(in XML) are presented as equivalent, which is not strictly true.Interceptors registered via
<mvc:interceptors/>are added asMappedInterceptors to the ApplicationContext to be later picked up byAbstractHandlerMapping.detectMappedInterceptors(List<HandlerInterceptor>)(viainitApplicationContext()) and added to the list of Interceptors.Interceptors configured via
WebMvcConfigurer.addInterceptors()(orWebMvcConfigurationSupport) will be directly set as Interceptors via a call toAbstractHandlerMapping.setInterceptors()(inrequestMappingHandlerMapping()).As a result,
FlowHandlerMapping(and possibly others) will be aware of Interceptors if these are configured via XML, but not via recommended Java Config.As far as I understand it, there is one workaround and the possibility to make the configuration explicit.
Workaround
Instead of adding the Interceptor in
addInterceptors(), a bean of typeMappedInterceptoris defined in the configuration class:That way the Interceptor gets picked up the same way as being configured via
<mvc:interceptors/>(while not being obvious).Explicit configuration
The Interceptor is configured as bean, added in
addInterceptors()and available for usage in other handlers (in this example Spring Web FlowsFlowHandlerMapping).Proposed Solution
To document this difference in behavior, I would propose another "Note" in the documentation. Something like:
Wishlist
I am aware of the falling out of favor of the "Open Session in View" pattern and prevalent usage of other web technologies not depending on server rendering and therefore Spring Web Flow. At the same time, I think there are many applications out there using these technologies and pattern. Therefore I would appreciate it, if you could use
OpenSessionInViewInterceptoras example in your documentation (perhaps even mentioningFlowHandlerMapping) to make it web searchable and obvious, that there is something to consider while switching from XML to Java Config