Разрешить Spring иметь несколько реализаций WebMvcConfigurer в разных банках

При использовании 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/**");
    }
}

Я добавил этот перехватчик в большинство своих приложений автоматически, выполнив следующие действия:

  1. Создайте «common-jar» и поместите вышеуказанный интерфейс в package
    com.company.api.
  2. В каждом приложении добавьте пакет com.company.api в апи сканирование.

Этот общий пакет также содержит классы Interceptor и утилиты, чтобы заставить этот перехватчик работать, поэтому, по сути, добавление этого common-jar автоматически добавит перехватчик ко всем операциям в приложении, что аналогично тому, что делает сам Spring: добавление зависимости изменяют конфигурацию Spring по умолчанию.

Проблема, с которой я столкнулся сейчас, заключается в том, что этот подход нельзя распространить на второй перехватчик во второй банке, потому что я уже использовал реализацию WebMvcConfigurer. и я не могу иметь два.

Я думал о том, чтобы, возможно, использовать какой-то шаблон составного конфигуратора, где мы перебираем каждый конфигуратор, собираем все перехватчики, а затем добавляем их один раз, но, к сожалению, Spring не позволяет этого. Каковы мои варианты?

В настоящее время подход, который я использовал, заключается в дублировании интерфейса WebMvcConfigurer в каждом приложении, которое его требует. Мне грустно, когда что-то меняется, и мне приходится менять один и тот же фрагмент кода в каждом отдельном приложении.

«Проблема, с которой я столкнулся сейчас, заключается в том, что этот подход нельзя распространить на второй перехватчик во втором банке, потому что я уже использовал реализацию WebMvcConfigurer, и у меня не может быть двух». Почему нельзя использовать несколько реализаций WebMvcConfigurer?
Dirk Deyne 30.05.2019 16:38

Spring позволяет использовать несколько WebMvcConfigurer, в чем ваша настоящая проблема?

Mạnh Quyết Nguyễn 30.05.2019 17:49

Вам не кажется, что здесь вам поможет шаблон API Gateway? Всего один шлюз API поможет вам управлять несколькими вещами? Просто мысль.

Bilbo Baggins 31.05.2019 09:54

@DirkDeyne Что ж, если реализация A возвращает реестр только с перехватчиком A, а реализация B возвращает реестр только с перехватчиком B, оба реестра будут объединены в один суперреестр, содержащий как A, так и B, или он просто выберет один, или будет выдает ошибку, что не было уникального определения bean-компонента?

user1884155 31.05.2019 12:07

@MạnhQuyếtNguyễn см. комментарий к DirkDeyne. Где задокументировано, что разрешено несколько WebMvcConfigurer и как они ведут себя, если оба реализуют один и тот же материал (в данном случае InterceptorRegistry)?

user1884155 31.05.2019 12:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
5
3 268
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если я правильно понимаю вашу проблему, вы не хотите реализовывать все методы 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 по умолчанию «суммируется»?

user1884155 03.06.2019 09:53

Другие вопросы по теме