当使用 Spring Web 时,在这种情况下,对于 rest 端点和使用 Spring Boot 2,我可以通过实现 WebMvcConfigurer
接口(interface)为我的应用程序配置拦截器:
@Configuration
public class SpringWebConfig implements WebMvcConfigurer
{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor).addPathPatterns("/api/endpoint/**");
}
}
我通过执行以下操作以自动方式将此拦截器添加到我的大多数应用程序中:
- 创建一个“common-jar”,把上面的接口(interface)放到package下
com.company.api
。 - 在每个应用程序中,将包
com.company.api
添加到 api 扫描。
这个通用包还包含Interceptor和实用程序类来使这个拦截器工作,所以实际上,添加这个common-jar会自动将他的拦截器添加到应用程序中的所有操作中,这与Spring本身的概念类似do: 添加依赖会改变 Spring 的默认配置。
我现在面临的问题是这种方法无法扩展到第二个 jar 中的第二个拦截器,因为我已经使用了 WebMvcConfigurer
实现。我不能有两个。
我正在考虑使用某种复合配置器模式,我们循环遍历每个配置器,收集所有拦截器,然后添加一次,但不幸的是 Spring 不允许这样做。我有哪些选择?
目前,我采用的方法是在每个需要它的应用程序中复制 WebMvcConfigurer
接口(interface)。当某些事情发生变化时我会感到难过,我必须在每个应用程序中更改相同的代码片段。
最佳答案
如果我正确理解你的问题,基本上你想在多个 JAR 中定义一些常见的 Interceptors
以便应用程序可以通过简单地将这些 JAR 包含到它们的中来激活这些 Interceptors
应用程序 ?
I was thinking about maybe using some kind of composite-configurer pattern where we loop over every configurer, collect all interceptors, and then add them once, but unfortunately Spring doesn't allow this. What are my options?
Well, if implementation A returns a registry with only interceptor A, and implementation B returns a registry with only interceptor B, would spring combine both registries into one super registry containing both A and B, or would it just pick one, or would it throw an error that there was no unique bean definition ?
其实Spring已经实现了this feature .当有多个 WebMvcConfigurer
bean 时,Spring 只需 loop them one by one并调用他们的配置方法。所以最终结果是 InterceptorRegistry
将包含所有拦截器。
如果客户端应用程序只需要激活某些 WebMvcConfigurer
,它可以简单地排除那些包含他们不想要的 WebMvcConfigurer
的 JAR。
为了让应用程序能够控制哪些 Interceptors
激活到拦截器级别,您甚至可以在每个常见 JAR 中执行以下操作:
@Configuration
public class SpringWebConfig implements WebMvcConfigurer {
//Make sure the HandlerInterceptor implementation in this JAR is a bean (e.g mark it as @Component)
@Autowired
private List<HandlerInterceptor> interceptors;
@Override
public void addInterceptors(InterceptorRegistry registry) {
for(HandlerInterceptor interceptor : interceptors){
registry.addInterceptor(interceptor).addPathPatterns("/api/endpoint/**");
}
}
}
在客户端应用程序中,使用 @ComponentScan
中的 includeFilters
/excludeFilters
来自定义要包含哪些拦截器。例如,要禁用某些 Interceptors
,你可以这样做:
@ComponentScan(
basePackages = {"com.company.api"},
excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=com.company.common.jar1.Inteceptor1.class) ,
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=com.company.common.jar2.Inteceptor1.class)
})
关于java - 允许 Spring 在不同的 jars 中有多个 WebMvcConfigurer 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56216178/