Контролиране на реда за създаване на боб с анотация @DependsOn

1. Общ преглед

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

Но все пак можем да го персонализираме според нашите нужди. Можем да изберем или интерфейса SmartLifeCycle, или анотацията @DependsOn за управление на реда за инициализация .

Този урок изследва анотацията @DependsOn и нейното поведение в случай на липсващ боб или кръгова зависимост. Или в случай, че просто се нуждаете от един боб, инициализиран преди друг.

2. Мейвън

На първо място, нека импортираме зависимостта spring-context в нашия файл pom.xml . Винаги трябва да се обърнем към Maven Central за най-новата версия на зависимости:

 org.springframework spring-context 5.2.8.RELEASE 

3. @DependsOn

Трябва да използваме тази анотация за определяне на зависимости на боб. Spring гарантира, че дефинираните зърна ще бъдат инициализирани, преди да се опита инициализация на текущия боб.

Да приемем, че имаме FileProcessor, който зависи от FileReader и FileWriter . В този случай FileReader и FileWriter трябва да бъдат инициализирани преди FileProcessor .

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(); } }

FileProcessor определя своите зависимости с @DependsOn . Можем също да анотираме Компонент с @DependsOn:

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

5. Употреба

Нека създадем един клас файл . Всеки от компонентите актуализира текста във файла . FileReader го актуализира като прочетен. FileWriter го актуализира като пише, а FileProcessor актуализира текста, както е обработен:

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

5.1. Липсваща зависимост

В случай на липсваща зависимост, Spring изхвърля BeanCreationException с основно изключение NoSuchBeanDefinitionException . Прочетете повече за NoSuchBeanDefinitionException тук.

Например, dummyFileProcessor боб зависи от dummyFileWriter боб. Тъй като dummyFileWriter не съществува, той изхвърля 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, трябва да използваме сканиране на компоненти
  • Ако DependsOn -annotated клас е обявен чрез XML, DependsOn анотация метаданни се игнорира

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

@DependsOn става особено полезен при изграждане на системи със сложни изисквания за зависимост.

Той улеснява инжекцията на зависимостите, като гарантира, че Spring ще е обработил цялата инициализация на необходимите Beans, преди да зареди зависимия ни клас.

Както винаги, кодът може да бъде намерен в GitHub.