Рубрики
Без рубрики

Управление порядком создания бобов с помощью аннотации @dependsOn

В этом учебнике рассматривается управление порядком инициализации Spring с помощью аннотации @dependsOn

Автор оригинала: baeldung.

1. Обзор

Spring по умолчанию управляет жизненным циклом бобов и упорядочивает их порядок инициализации.

Но мы все еще можем настроить его в соответствии с нашими потребностями. Мы можем выбрать либо интерфейс SmartLifecycle , либо аннотацию @dependsOn для управления порядком инициализации .

Этот учебник исследует аннотацию @dependsOn и ее поведение в случае отсутствия боба или циклической зависимости . Или в случае просто необходимости инициализации одного из них перед другим.

2. Maven

Прежде всего, давайте импортируем зависимость spring-context в ваш pom.xml файл. Мы всегда должны обращаться к Maven Central за последней версией зависимостей:


    org.springframework
    spring-context
    5.2.8.RELEASE

3. @dependsOn

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

Допустим, у нас есть Файловый процессор , который зависит от FileReader и FileWriter . В этом случае FileReader и FileWriter должны быть инициализированы перед Файловым процессором .

4. Конфигурация

Файл конфигурации представляет собой чистый класс Java с аннотацией @Configuration :

@Configuration
@ComponentScan("com.baeldung.dependson")
public class Config {
 
    @Bean
    @DependsOn({"fileReader","fileWriter"})
    public FileProcessor fileProcessor(){
        return new FileProcessor();
    }
    
    @Bean("fileReader")
    public FileReader fileReader() {
        return new FileReader();
    }
    
    @Bean("fileWriter")
    public FileWriter fileWriter() {
        return new FileWriter();
    }   
}

Файловый процессор определяет свои зависимости с помощью @dependsOn . Мы также можем аннотировать Компонент с помощью @dependsOn:

@Component
@DependsOn({"filereader", "fileWriter"})
public class FileProcessor {}

5. Использование

Давайте создадим один класс File . Каждый из бобов обновляет текст внутри File . File Reader обновляет его как прочитанный. FileWriter обновляет его как запись и Файловый процессор обновляет текст как обработанный:

@Test
public void WhenFileProcessorIsCreated_FileTextContains_Processed() {
    FileProcessor processor = context.getBean(FileProcessor.class);
    assertTrue(processor.process().endsWith("processed"));
}

5.1. Отсутствующая Зависимость

В случае отсутствия зависимости Spring выдает исключение BeanCreationException с базовым исключением NoSuchBeanDefinitionException . Подробнее о NoSuchBeanDefinitionException | читайте здесь .

Например, dummy File Processor bean зависит от dummy File Writer bean. Поскольку dummy File Writer не существует, он выдает BeanCreationException:

@Test(expected=NoSuchBeanDefinitionException.class)
public void whenDependentBeanNotAvailable_ThrowsNosuchBeanDefinitionException(){
    context.getBean("dummyFileProcessor");
}

5.2. Циклическая зависимость

Кроме того, в этом случае он выбрасывает BeanCreationException и подчеркивает, что бобы имеют циклическую зависимость:

@Bean("dummyFileProcessorCircular")
@DependsOn({"dummyFileReaderCircular"})
@Lazy
public FileProcessor dummyFileProcessorCircular() {
    return new FileProcessor(file);
}

Круговые зависимости могут возникать , если боб имеет возможную зависимость от самого себя , создавая круг:

Bean1 -> Bean4 -> Bean6 -> Bean1

6. Ключевые моменты

Наконец, есть несколько моментов, о которых мы должны позаботиться при использовании @dependsOn аннотации:

  • Во время использования @dependsOn, мы должны использовать компонентное сканирование
  • Если Зависит от -аннотированный класс объявлен через XML, Зависит от метаданные аннотаций игнорируются

7. Заключение

@dependsOn становится особенно полезным при построении систем со сложными требованиями к зависимостям.

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

Как всегда, код можно найти на GitHub .