【发布时间】:2023-03-18 09:38:01
【问题描述】:
我正在努力寻找一种从一个或多个附加模块(在本例中为 Maven 模块)中添加请求拦截器的方法。
在主模块中,有一个 Web MVC 配置类,如下所示:
@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 注入应用程序启动的事件侦听器类并通过 requestMappingHandlerMapping.setInterceptors(myCustomerInterceptorArray) 添加自定义拦截器来实现这一点。不幸的是,这并不完全奏效。似乎正在添加拦截器,但 Spring 使用另一个拦截器列表 - adaptedInterceptors - 用于执行链。不幸的是,似乎没有任何公共方法可用于将拦截器添加到 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);
}
}
}
这种方法的唯一问题是没有一种非常好的方法来订购拦截器。这可以通过自定义解决方案来解决,例如在每个拦截器类上添加一个订单注释,并在将它们添加到注册表时考虑到这一点。但它仍然感觉不是 100% 干净。所以我仍然希望有更好的方法。
【问题讨论】:
-
只需添加一个实现
DelegatingWebMvcConfiguration或扩展WebMvcConfigurerAdapter的bean 并添加它。只需将此类添加到您的模块中。不要在根应用程序中扩展DelegatingWebMvcConfiguration,只需添加一个带有@EnableWebMvc注释的@Configuration类来自定义您的配置,您可以使用WebMvcConfigurer。配置 mvc 内容时会考虑所有实现WebMvcConfigurer的 bean。 -
感谢您的评论!不确定我是否完全理解,我似乎仍然无法让它工作。在我的主模块中,我正在扩展
DelegatingWebMvcConfiguration而不是使用EnableWebMvc注释,因为我在那里进行了一些高级配置。我的理解是拥有一个扩展DelegatingWebMvcConfiguration的@Configuration类相当于使用@EnableWebMvc。我尝试添加实现WebMvcConfigurer的@Configuration类和实现相同的bean。但是对于任何一个,我都没有看到addInterceptors方法被调用。 -
如果您扩展
DelegatingWebMvcConfiguration并覆盖其中的某些方法,则不再发生委派。因此它不起作用。你在做什么配置?通常,您不必扩展DelegatingWebMvcConfiguration,并且您可能希望在添加拦截器和高级配置时分开处理(但也许您可以添加完整的配置类)。 -
谢谢,我没有意识到默认实现是咨询所有配置器,而覆盖它会破坏该功能。在覆盖方法中添加
super.addInterceptors(registry)后,它看起来像预期的那样工作。我不得不扩展DelegatingWebMvcConfiguration一段时间,因为如果我没记错的话,可以通过WebMvcConfigurerAdapter配置消息转换器的方式受到限制。我将回顾一下,看看最新的 Spring 版本现在是否不需要这样做。再次感谢!
标签: java spring spring-mvc spring-boot