При использовании Spring Web, в данном случае для остальных конечных точек и с использованием Spring Boot 2, я могу настроить перехватчики для своего приложения, используя интерфейс WebMvcConfigurer:
@Configuration
public class SpringWebConfig implements WebMvcConfigurer
{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor).addPathPatterns("/api/endpoint/**");
}
}
Я добавил этот перехватчик в большинство своих приложений автоматически, выполнив следующие действия:
com.company.api.com.company.api в
апи сканирование.Этот общий пакет также содержит классы Interceptor и утилиты, чтобы заставить этот перехватчик работать, поэтому, по сути, добавление этого common-jar автоматически добавит перехватчик ко всем операциям в приложении, что аналогично тому, что делает сам Spring: добавление зависимости изменяют конфигурацию Spring по умолчанию.
Проблема, с которой я столкнулся сейчас, заключается в том, что этот подход нельзя распространить на второй перехватчик во второй банке, потому что я уже использовал реализацию WebMvcConfigurer. и я не могу иметь два.
Я думал о том, чтобы, возможно, использовать какой-то шаблон составного конфигуратора, где мы перебираем каждый конфигуратор, собираем все перехватчики, а затем добавляем их один раз, но, к сожалению, Spring не позволяет этого. Каковы мои варианты?
В настоящее время подход, который я использовал, заключается в дублировании интерфейса WebMvcConfigurer в каждом приложении, которое его требует. Мне грустно, когда что-то меняется, и мне приходится менять один и тот же фрагмент кода в каждом отдельном приложении.
Spring позволяет использовать несколько WebMvcConfigurer, в чем ваша настоящая проблема?
Вам не кажется, что здесь вам поможет шаблон API Gateway? Всего один шлюз API поможет вам управлять несколькими вещами? Просто мысль.
@DirkDeyne Что ж, если реализация A возвращает реестр только с перехватчиком A, а реализация B возвращает реестр только с перехватчиком B, оба реестра будут объединены в один суперреестр, содержащий как A, так и B, или он просто выберет один, или будет выдает ошибку, что не было уникального определения bean-компонента?
@MạnhQuyếtNguyễn см. комментарий к DirkDeyne. Где задокументировано, что разрешено несколько WebMvcConfigurer и как они ведут себя, если оба реализуют один и тот же материал (в данном случае InterceptorRegistry)?




Если я правильно понимаю вашу проблему, вы не хотите реализовывать все методы WebMvcConfigurer в каждом приложении. Вы просто хотите добавить соответствующие перехватчики и покончить с этим.
Мой подход состоял бы в том, чтобы создать AbstractWebMvcConfigurerImpl, внедрив WebMvcConfigurer в модуль Common. Просто оставьте абстракцию addInterceptors() и реализуйте другие методы. Затем вы можете расширить эту абстрактную реализацию в каждом своем проекте Spring Boot и просто переопределить метод addInterceptors() в соответствии с вашими потребностями.
Кроме того, вы можете иметь столько реализаций WebMvcConfigurer, сколько хотите в проекте Spring. Итак, если вам нужно определить некоторые общие перехватчики в модуле Common, вы также можете расширить AbstractWebMvcConfigurerImpl в общем модуле.
Обратите внимание, что все ваши реализации AbstractWebMvcConfigurerImpl должны быть аннотированы @Configuration
Если я правильно понимаю ваш вопрос, в основном вы хотите определить некоторые общие Interceptors в нескольких JAR-файлах, чтобы приложение могло активировать их Interceptors, просто включив эти JAR-файлы в свое приложение?
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 уже реализовал эта особенность. Когда есть несколько WebMvcConfigurer bean-компонентов, Spring просто зациклить их один за другим и вызывает их методы конфигурации. Таким образом, конечным результатом является то, что InterceptorRegistry будет содержать все перехватчики.
Если клиентскому приложению необходимо активировать только определенные WebMvcConfigurer, оно может просто исключить те JAR-файлы, содержащие WebMvcConfigurer, которые ему не нужны.
Чтобы развить эту идею, позволяющую приложению контролировать, какие 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/**");
}
}
}
В клиентском приложении используйте includeFilters / excludeFilters в @ComponentScan, чтобы указать, какие перехватчики включать. Например, чтобы отключить определенные 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)
})
Является ли CompositeWebMvcConfigruer «активным по умолчанию», что означает, что результат всех webmcvconfigurers по умолчанию «суммируется»?