задний план
В классе запуска SpringBoot есть три способа настроить путь пакета сканирования. Недавно я увидел, что все три аннотации используются в приложении. Код выглядит следующим образом:
@SpringBootApplication(scanBasePackages ={"a","b"})
@ComponentScan(basePackages = {"a","b","c"})
@MapperScan({"XXX"})
public class XXApplication extends SpringBootServletInitializer
}
Итак, вопрос: каковы эффективные приоритеты этих трех аннотаций в SpringBoot и есть ли разница между первой и второй? В этой статье приведены меры предосторожности для этих трех аннотаций.
Аннотация SpringBootApplication
Это аннотация SpringBoot, которая по сути представляет собой сумму трех аннотаций Spring.
- @Configuration
- @EnableAutoConfiguration
- @ComponentScan
Он сканирует пакет, в котором находится класс запуска, и все его подпакеты по умолчанию.Но другие каталоги, которые не включают сторонние пакеты jar,пройти черезscanBasePackages
Свойства могут сбросить путь пакета сканирования.
Уведомление: если нам нужно сканировать аннотации в зависимом пакете jar, а путь зависимого пакета не включен в путь к классам запуска SpringBoot, мы должны использовать его отдельно@ComponentScan
Annotation сканирует сторонние пакеты. При этом должен быть указан путь сканирования этого проекта.Поскольку при наличии этой аннотации она имеет приоритет, а пакет сканирования по умолчанию недействителен..
Например этот проект:Каталог проекта класса запуска 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 окончательно исчезнут.