Spring IoC контейнер: сканирование classpath, автоматическое определение классов и регистрация определений бинов

Spring может автоматически обнаруживать стереотипные классы и регистрировать соответствующие экземпляры BeanDefinition с помощью ApplicationContext. Например, следующие два класса имеют право на такое автоопределение:

Java

@Service
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

Kotlin

@Service
class SimpleMovieLister(private val movieFinder: MovieFinder)

Java

@Repository
public class JpaMovieFinder implements MovieFinder {
    // реализация исключена для ясности
}

Kotlin

@Repository
class JpaMovieFinder : MovieFinder {
    // реализация исключена для ясности
}

Для автоматического определения этих классов и регистрации соответствующих bean-компонентов вам необходимо добавить @ComponentScan в ваш класс @Configuration, где атрибут basePackages является общим родительским пакетом для этих двух классов. (В качестве альтернативы вы можете указать список через запятую или точку с запятой или через пробел, который включает родительский пакет каждого класса.)

Java

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

Kotlin

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

Для краткости в предыдущем примере мог использоваться атрибут value аннотации (то есть @ComponentScan("org.example")).

Следующая альтернатива использует XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

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

Использование <context:component-scan> неявно включает функциональность <context:annotation-config>. Обычно нет необходимости включать элемент <context:annotation-config> при использовании <context:component-scan>.

Сканирование пакетов classpath требует наличия соответствующих записей каталога в classpath. Когда вы создаете JAR-файлы с помощью Ant, убедитесь, что вы не активировали переключатель "только для файлов" задачи JAR. Кроме того, каталоги classpath могут не отображаться в зависимости от политик безопасности в некоторых средах, например, в автономных приложениях на JDK 1.7.0_45 и выше (для которых в манифестах требуется настройка Trusted-Library).

На пути к модулю JDK 9 (Jigsaw) сканирование classpath Spring обычно работает как положено. Однако убедитесь, что ваши классы компонентов экспортируются в ваших дескрипторах информации модуля. Если вы ожидаете, что Spring будет вызывать непубличные члены ваших классов, убедитесь, что они "открыты" (то есть, что они используют декларацию opens вместо декларации exports в вашем дескрипторе информации модуля).

Кроме того, AutowiredAnnotationBeanPostProcessor и CommonAnnotationBeanPostProcessor оба неявно включаются при использовании элемента компонентного сканирования. Это означает, что оба компонента автоматически определяются и соединяются вместе - и все это без каких-либо метаданных конфигурации bean-компонентов, предоставляемых в XML.

Вы можете отключить регистрацию AutowiredAnnotationBeanPostProcessor и CommonAnnotationBeanPostProcessor, включив атрибут annotation-config со значением false.


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


Комментарии

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

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

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

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