Contrôle de l'ordre de création de bean avec l'annotation @DependsOn

1. Vue d'ensemble

Spring, par défaut, gère le cycle de vie des beans et organise leur ordre d'initialisation.

Mais nous pouvons toujours le personnaliser en fonction de nos besoins. Nous pouvons choisir soit l' interface SmartLifeCycle , soit l' annotation @DependsOn pour gérer l'ordre d'initialisation .

Ce tutoriel explore l' annotation @DependsOn et son comportement en cas de bean manquant ou de dépendance circulaire. Ou en cas de simple besoin d'un bean initialisé avant un autre.

2. Maven

Tout d'abord, importons la dépendance spring-context dans notre fichier pom.xml . Nous devons toujours nous référer à Maven Central pour la dernière version des dépendances:

 org.springframework spring-context 5.2.8.RELEASE 

3. @DependsOn

Nous devrions utiliser cette annotation pour spécifier les dépendances de bean. Spring garantit que les beans définis seront initialisés avant de tenter une initialisation du bean courant.

Disons que nous avons un FileProcessor qui dépend d'un FileReader et FileWriter . Dans ce cas, FileReader et FileWriter doivent être initialisés avant FileProcessor .

4. Configuration

Le fichier de configuration est une pure classe Java avec l' annotation @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 spécifie ses dépendances avec @DependsOn . Nous pouvons également annoter un composant avec @DependsOn:

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

5. Utilisation

Créons un fichier de classe . Chacun des beans met à jour le texte dans File . FileReader le met à jour comme lu. FileWriter le met à jour en écriture et FileProcessor met à jour le texte comme traité:

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

5.1. Dépendance manquante

En cas de dépendance manquante, Spring lève une exception BeanCreationException avec une exception de base NoSuchBeanDefinitionException . En savoir plus sur NoSuchBeanDefinitionException ici.

Par exemple, le bean dummyFileProcessor dépend d'un bean dummyFileWriter . Puisque dummyFileWriter n'existe pas, il lève BeanCreationException:

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

5.2. Dépendance circulaire

De plus, dans ce cas, il lance BeanCreationException et met en évidence que les beans ont une dépendance circulaire:

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

Des dépendances circulaires peuvent se produire si un bean a une éventuelle dépendance sur lui - même , créant un cercle:

Bean1 -> Bean4 -> Bean6 -> Bean1

6. Points clés

Enfin, il y a quelques points à prendre en compte lors de l'utilisation de l' annotation @DependsOn :

  • Lors de l'utilisation de @DependsOn, nous devons utiliser l'analyse des composants
  • Si une classe annotée DependsOn est déclarée via XML, les métadonnées d'annotation DependsOn sont ignorées

7. Conclusion

@DependsOn devient particulièrement utile lors de la construction de systèmes avec des exigences de dépendance complexes.

Il facilite l'injection de dépendances, garantissant que Spring aura géré toute l'initialisation de ces Beans requis avant de charger notre classe dépendante.

Comme toujours, le code peut être trouvé sur GitHub.