在 Web MVC 配置之外添加请求拦截器 class

Add request interceptor outside of Web MVC configuration class

我正在努力寻找一种方法来从一个或多个附加模块(在这种情况下模块是 Maven 模块)中添加请求拦截器。

在主模块中,有一个 Web MVC 配置 class 如下所示:

@Configuration
public class WebMvcConfig extends DelegatingWebMvcConfiguration {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // main module interceptors are registered here via
        // registry.addInterceptor(interceptor);
    }

}

现在,在附加模块 1 中我有 MyFirstCustomInterceptor,在附加模块 2 中有 MySecondCustomInterceptor,我想将它们添加到同一个拦截器注册表中。我觉得这应该很容易,但在阅读官方 Spring MVC 文档时找不到明显的方法。

文档中提到并且听起来很有希望的一种方法是使用 RequestMappingHandlerMapping bean 及其 setInterceptors(Object[] interceptors) 方法。

我通过将 bean 注入应用程序启动的事件侦听器 class 并通过 requestMappingHandlerMapping.setInterceptors(myCustomerInterceptorArray) 添加自定义拦截器来尝试这样做。不幸的是,这并没有奏效。似乎正在添加拦截器,但 Spring 使用另一个拦截器列表 - adaptedInterceptors - 用于执行链。不幸的是,似乎没有任何 public 方法可用于将拦截器添加到 adaptedInterceptors 列表。

我在想,也许RequestMappingHandlerMapping.setInteceptors()方法需要更早的调用,或者必须有办法将WebMvcConfig扩展到附加模块。但我不确定该怎么做。

编辑:

我刚才的另一个想法是基于注入所有 HandlerInterceptor 个 bean 的列表。例如:

@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);
        }
    }

}

这种方法的唯一问题是没有真正好的方式来对拦截器进行排序。这可以通过自定义解决方案来解决,比如在每个拦截器 class 上添加一个顺序注释,并在将它们添加到注册表时考虑到这一点。但它仍然感觉不到 100% 干净。所以我还是希望有更好的办法。

通常在使用 Spring MVC 时,您应该有一个基于 class 和 @EnableWebMvc 的配置。

这将在您的根配置中

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {        
        // Add the interceptors for the root here.
    }
}

现在在您的其他项目中只需添加一个配置 class,它只添加拦截器。

@Configuration
public class ModuleAWebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {        
        // Add the interceptors for the Module A here.
    }
}

配置Spring@MVC.

时会参考所有WebMvcConfigurers

然而,在您的情况下,这是行不通的,因为您已经扩展了 DelegatingWebMvcConfiguration 并破坏了委托,因为您已经覆盖了 addInterceptors 方法。

该方法的默认实现是

protected void addInterceptors(InterceptorRegistry registry) {
    this.configurers.addInterceptors(registry);
}

它会查询所有 configurers(它检测到的 WebMvcConfigurer)。但是,由于您的覆盖方法,这不再发生,并且正常的扩展机制不再起作用。