Во время разработки мне понадобилось создать бин с функционалом, который нужен в нескольких микросервисах. Для того, чтобы переиспользовать код и не дублировать логику в этих сервисах, решила вынести бин в уже существующую библиотеку. В связи с этим решила написать небольшую заметку о том, как Spring ищет кандидатов для создания бинов.
Если просто создать класс с нужным функционалом в библиотеке, пометить его как
@Component, и подключить библиотеку в проект в качестве зависимости, создаст ли фреймворк этот бин? Ответ - нет. В приложении Spring Boot, application класс обычно помечается аннотацией
@SpringBootApplication, которая включает в себя аннотацию @ComponentScan. И фреймворк будет сканировать на предмет наличия бинов только пакет, в котором объявлен класс помеченный какой-либо из этих аннотаций, и его подпакеты. Spring не сканирует весь classpath или все приложение для поиска бинов.
Если надо инжектировать в класс бин из подключенной библиотеки, например ru.mylib.MyBean, можно, например, добавить к application классу аннотацию
@ComponentScan("ru.mylib").Есть и другой способ - использовать spring boot starters.
Чем стартер отличается от библиотеки? Помимо того, что стартер обычно содержит набор библиотек, стартеры включают в себя автоконфигурации.
Автоконфигурация - это класс конфигурации, помеченный анннотацией
@Configuration или @AutoConfiguration. В стартере они должны быть перечислены в файле spring.factories или org.springframework.boot. autoconfigure.AutoConfiguration.imports. При запуске приложения Spring Boot сканирует classpath, и находит все jar с данными файлами. И создает все бины, которые объявлены в файлах автоконфигурации.В частности, можно превратить нашу библиотеку myLib в стартер, добавив автоконфигурацию с аннотацией
@ComponentScan("ru.mylib"), и тогда все бины из данного пакета будут созданы и доступны во время работы приложения.