JWK
JWK

Reputation: 740

Add request interceptor outside of Web MVC configuration class

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

Answers (1)

M. Deinum
M. Deinum

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 WebMvcConfigurers 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 WebMvcConfigurers it detected). However due to your overriden method this isn't happening anymore and the normal extension mechanism isn't working anymore.

Upvotes: 0

Related Questions