Принципы использования и конфликты при сканировании аннотаций классов запуска SpringBoot

Spring Boot

задний план

В классе запуска SpringBoot есть три способа настроить путь пакета сканирования. Недавно я увидел, что все три аннотации используются в приложении. Код выглядит следующим образом:

@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer 
}

Итак, вопрос: каковы эффективные приоритеты этих трех аннотаций в SpringBoot и есть ли разница между первой и второй? В этой статье приведены меры предосторожности для этих трех аннотаций.

Аннотация SpringBootApplication

Это аннотация SpringBoot, которая по сути представляет собой сумму трех аннотаций Spring.

  1. @Configuration
  2. @EnableAutoConfiguration
  3. @ComponentScan

Он сканирует пакет, в котором находится класс запуска, и все его подпакеты по умолчанию.Но другие каталоги, которые не включают сторонние пакеты jar,пройти черезscanBasePackagesСвойства могут сбросить путь пакета сканирования.

Уведомление: если нам нужно сканировать аннотации в зависимом пакете jar, а путь зависимого пакета не включен в путь к классам запуска SpringBoot, мы должны использовать его отдельно@ComponentScanAnnotation сканирует сторонние пакеты. При этом должен быть указан путь сканирования этого проекта.Поскольку при наличии этой аннотации она имеет приоритет, а пакет сканирования по умолчанию недействителен..

Например этот проект:在这里插入图片描述Каталог проекта класса запуска SpringBoot:cn.com.a.b, ссылаясь на сторонние общедоступные пакетыxxx.common.jarКаталог такжеcn.com.a.b, то аннотации в стороннем пакете jar можно будет сканировать напрямую. В других jar-пакетах, если есть аннотации, их нельзя отсканировать.

Аннотация ComponentScan

Это аннотация фреймворка Spring, которая используется для указания пути сканирования компонента.Если эта аннотация используется, ее значение должно содержать все пути, которые нужно сканировать во всем проекте. потому что он перезапишетSpringBootApplicationПуть сканирования по умолчанию для , что приводит к сбою.

Существует два типа отказов:

Во-первых, еслиComponentScanСодержит только одно значение и является каталогом класса запуска по умолчанию.SpringBootApplicationвступать в силу,ComponentScanАннотация недействительна, и сообщается об ошибке:在这里插入图片描述Во-вторых, еслиComponentScanУкажите несколько конкретных подкаталогов, в настоящее времяSpringBootApplicationпотерпит неудачу, Spring будет только сканироватьComponentScanАннотация в указанном каталоге. Если у вас есть классы контроллеров вне каталога, к сожалению, эти контроллеры будут недоступны.

Вернемся к коду в начале:

@SpringBootApplication(scanBasePackages ={})
@ComponentScan(basePackages = {})

указано здесьComponentScanПосле комментирования,scanBasePackagesне удастся. Следовательно, еслиComponentScanизbasePackagesСтоимость не включаетcn.com.a.bТо есть пакет, в котором находится класс запуска, и указан только каталог стороннего jar, тоЛюбые аннотации в этом проекте не могут быть отсканированы.

Аннотации MapperScan

Это аннотация MyBatis, которая инкапсулирует все классы DAO в указанном каталоге в MyBatis.BaseMapperкласс, а затем внедрить его в контейнер Spring,Никаких дополнительных аннотаций не требуется, инъекцию можно завершить.

Откровение

Путь сканирования пакета SpringBoot, противоречивое поведение двух аннотаций, я давно неоднократно проверял явление, но разумного объяснения так и не нашел. Эта статья назревала в черновике почти две недели и была приостановлена.

Сегодня я нашел статью, в которой говорилось, что когда они используются одновременно,SpringBootApplicationЭто не удастся, и сомнения относительно пути сканирования SpringBoot окончательно исчезнут.