Spring IoC контейнер: сканирование classpath, именование автоопределенных компонентов

Когда компонент автоматически определяется как часть процесса сканирования, его имя компонента создается стратегией BeanNameGenerator, известной этому сканеру. По умолчанию любая стереотипная аннотация Spring (@Component, @Repository, @Service и @Controller), которая содержит значение имени, тем самым предоставляет это имя соответствующему определению компонента.

Если такая аннотация не содержит значения имени или какого-либо другого обнаруженного компонента (например, обнаруженного с помощью пользовательских фильтров), генератор имен компонентов по умолчанию возвращает некапитализированное неквалифицированное имя класса. Например, если были обнаружены следующие классы компонентов, имена будут myMovieLister и movieFinderImpl:

Java

@Service("myMovieLister")
public class SimpleMovieLister {
    // ...
}

Kotlin

@Service("myMovieLister")
class SimpleMovieLister {
    // ...
}

Java

@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}

Kotlin

@Repository
class MovieFinderImpl : MovieFinder {
    // ...
}

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

Если вы столкнетесь с конфликтами имен из-за того, что несколько автоопределенных компонентов имеют одно и то же неквалифицированное имя класса (т. е. классы с одинаковыми именами, но находятся в разных пакетах), вам может потребоваться настроить BeanNameGenerator, в котором по умолчанию используется полное имя класса для сгенерированное имя бина. Начиная с версии Spring Framework 5.2.3, FullyQualifiedAnnotationBeanNameGenerator, расположенный в пакете org.springframework.context.annotation, может использоваться для таких целей.

Java

@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
    // ...
}

Kotlin

@Configuration
@ComponentScan(basePackages = ["org.example"], nameGenerator = MyNameGenerator::class)
class AppConfig {
    // ...
}

<beans>
    <context:component-scan base-package="org.example"
        name-generator="org.example.MyNameGenerator" />
</beans>

Как правило, рекомендуется указывать имя с аннотацией всякий раз, когда другие компоненты могут делать явные ссылки на него. С другой стороны, автоматически генерируемые имена являются адекватными, когда контейнер отвечает за подключение.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки