Reputation: 740
I'm struggling to find a way to add request interceptors from within one or more add-on modules (modules being Maven modules in this case).
In the main module, there is a Web MVC configuration class that looks like this:
@Configuration
public class WebMvcConfig extends DelegatingWebMvcConfiguration {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// main module interceptors are registered here via
// registry.addInterceptor(interceptor);
}
}
Now, in add-on module 1 I have MyFirstCustomInterceptor
and in add-on module 2 MySecondCustomInterceptor
which I would like to add to the same interceptor registry. I feel like this should be easy but I couldn't find an obvious way to do it when reading through the official Spring MVC documentation.
One approach, that is mentioned in the documentation and that sounded promising, was to use the RequestMappingHandlerMapping
bean and it's setInterceptors(Object[] interceptors)
method.
I tried that by injecting the bean into an application-started event listener class and adding the custom interceptors through requestMappingHandlerMapping.setInterceptors(myCustomerInterceptorArray)
. Unfortunately, that didn't quite work. It seems the interceptor is being added but Spring uses another interceptor list - adaptedInterceptors
- for the execution chain. Unfortunately, there don't seem to be any public methods available to add an interceptor to the adaptedInterceptors
list.
I'm thinking that maybe the RequestMappingHandlerMapping.setInteceptors()
method needs to be called earlier, or that there must be a way to extend the WebMvcConfig to the add-on module. But I'm unsure how that would be done.
Edit:
Another idea I just had, is based on injecting a list of all HandlerInterceptor
beans. For example:
@Configuration
public class WebMvcConfig extends DelegatingWebMvcConfiguration {
@Inject private List<HandlerInterceptor> handlerInterceptors;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Note: the order of the interceptors would likely be an issue here
for (HandlerInterceptor interceptor : handlerInterceptors) {
registry.addInterceptor(interceptor);
}
}
}
The only problem with this approach would be that there isn't a really good way to order the interceptors. That could be solved with a custom solution, like adding an order annotation on each interceptor class and taking that into account when adding them to the registry. But it still doesn't feel 100% clean. So I'm still hoping there is a better way.
Upvotes: 0
Views: 2689
Reputation: 125202
Generally when using Spring MVC you should have a configuration based class with @EnableWebMvc
.
This would be in your root configuration
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Add the interceptors for the root here.
}
}
Now in your additional projects just add a configuration class which only adds the interceptors.
@Configuration
public class ModuleAWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Add the interceptors for the Module A here.
}
}
All WebMvcConfigurer
s are consulted when configuring Spring @MVC.
In your case however that isn't going to work because you have extended DelegatingWebMvcConfiguration
and broke the delegation because you have overriden the addInterceptors
method.
The default implementation of that method is
protected void addInterceptors(InterceptorRegistry registry) {
this.configurers.addInterceptors(registry);
}
Which consults all configurers
(the WebMvcConfigurer
s it detected). However due to your overriden method this isn't happening anymore and the normal extension mechanism isn't working anymore.
Upvotes: 0