1. Восстановление места ошибки
круговая зависимость
1.1, в классе конфигурации перехватчика полагаться на перехватчик через конструктор и переписать функцию addInterceptors, чтобы внедрить перехватчик в цепочку перехватчиков.
1.2, а перехватчик также полагается на ThirdAuthClient через конструктор
1.3, ThirdAuthClient (фальшивый клиентский интерфейс)
Проект начинает сообщать об ошибке, показывая циклические зависимости этих трех классов.
2. Анализ ошибок
2.1 Гипотеза
Глядя на отчет об ошибке, первые две зависимости можно понять, но ThirdAuthClient зависит от ThirdInterceptorConfig и понять его невозможно, это всего лишь @FeignClient, который должен быть загружен после старта весны. Глядя на отношение диаграммы классов, я не вижу результата. Сначала я подозреваю, что это как-то связано с порядком загрузки Spring bean. Хотя я вижу круговую зависимость, на самом деле это может быть неправильный метод загрузки.
2.2 Кардочесание
Сначала обратите внимание на метод инъекции Spring MVC Interceptor.
Это способ регистрации перехватчика в официальном документе, который прямо новый. Тогда фокус становится:
Почему Interceptor нельзя внедрить через @Autowired или конструктор?
Сделал поиск и нашел это утверждение:
1. Правило сборки Bean проекта SpringBoot по умолчанию — сканирование сверху вниз в соответствии с расположением пакета ( com.boot.app ), в котором находится класс приложения.
2. Перехватчики выполняются до автоматической инициализации бина
Это утверждение согласуется с гипотезой, продолжайте думать: действительно ли перехватчик выполняется до автоматической инициализации бина
В моем случае использования, я думаю, правильный порядок должен быть
Все зависимости перехватчика (например, ThirdAuthClient) инициализируются bean-компонентами и внедряются в контейнер Spring.
Выполнить инъекцию перехватчика
Инициализируйте объект bean-перехватчика. В настоящее время объект bean-компонента, который уже существует в 1, требуется в качестве зависимости перехватчика
Перехватчик был успешно введен
Если вы так считаете, то утверждение 2 не соответствует этой идее, либо перехватчик, определенный в официальном документе, является обычным кастомом, на него не надо полагаться, просто новый, а мой кастомный перехватчикЗависимости явно объявляются через конструктор, возможно, это различие приводит к циклическим зависимостям.
Я нашел другие методы внедрения конструктора, а именно:
Его можно вводить через @Bean, затем ThirdAuthClient, который вызывает циклическую зависимость перехватчика, вводится через @Autowired, а другие классы вводятся через конструктор
Таким образом, когда последовательность 2 в моей идее выполняется, компоненты, необходимые для последовательности 1, готовы.
3. Анализ
Во-первых, в соответствии с порядком, в котором Spring загружает и создает экземпляры bean-компонентов, следующим образом
Ошибка циклической ссылки должна быть обнаружена Spring во время рекурсивного синтаксического анализа, и она как-то связана с инициализацией bean-компонента конструктором, который я написал. Методы внедрения перехватчиков, встречающиеся в Интернете, в основном создаются вручную.
Итак, здесь четкий вопрос:
1. Можно ли создать перехватчик только вручную (new out)? Разве Spring не может управлять объектами и создавать их?
Анализ: Этот процесс загрузки включает в себя@ConfigurationProperties
,@Component
,@FeignClient
,@Configuration
,@Component
эти аннотации
@ConfigurationProperties
Аннотация относится к аннотации класса конфигурации Spring и загружается первой.
@FeignClient
аннотация, авторFeignClientsRegistrar
класс реализуетImportBeanDefinitionRegistrar
,пройти черезregisterBeanDefinitions
метод вводится в контейнер@FeignClient
Аннотированный интерфейс
@Configuration
,@Component
, принадлежит классу конфигурации, Spring автоматически загружает
Согласно логике загрузки bean-компонентов Spring, эти аннотации находятся в видимой области действия Spring, и зависимости этих экземпляров могут быть проанализированы с помощью рекурсивного анализа и созданы в нужное время.
В этом анализе проблема может быть в конструкторе,Явное объявление конструктора заменяет метод рекурсивного анализа, на который опирается Spring при анализе этих экземпляров, в результате чего эти экземпляры не могут быть разрешены путем анализа зависимостей.Если вы не используете конструктор, то я думаю, что классы, объявленные этими аннотациями, могут обрабатываться в разрешении зависимостей Spring.
4. Осознайте
1. Вручную создайте реализацию экземпляра перехватчика
Перехватчик не добавляет никаких аннотаций автоконфигурации, предотвращает автоматическое связывание и инициализацию Spring и явно объявляет зависимости через конструктор.
Класс конфигурации перехватчика подготавливает bean-компоненты, необходимые перехватчику, через конструктор и @Autowired.
При выполнении последовательности 3 вручную создайте экземпляр перехватчика с помощью метода @Bean и передайте инициализацию перехватчика Spring.
Это делается без изменения метода конструктора, что возможно на практике.
2. Пусть контейнер Spring управляет созданием перехватчика
Это делается для того, чтобы удалить конструктор и использовать аннотации для замены ручного создания экземпляров перехватчика, что возможно на практике.
5. Вывод
Созданием перехватчика можно управлять с помощью управления контейнерами Spring вместо ручного создания.
Справочная документация
блог woo woo woo.cn на.com/desert89/afraid/8…
stackoverflow.com/questions/2…