Kontrolle der Bean-Erstellungsreihenfolge mit @DependsOn Annotation

Steuern der Bean-Erstellungsreihenfolge mit @DependsOn Annotation

1. Überblick

Standardmäßig verwaltet Spring den Lebenszyklus von Beans und ordnet deren Initialisierungsreihenfolge.

Trotzdem können wir es an unsere Bedürfnisse anpassen. We can choose either the SmartLifeCycle interface or the @DependsOn annotation for managing initialization order.

In diesem Lernprogramm werden die Annotation von@DependsOnund ihr Verhalten bei fehlenden Beans odercircular dependency untersucht. Oder wenn einfach eine Bean vor einer anderen initialisiert werden muss.

2. Maven

Importieren wir zunächst die Abhängigkeit vom Frühlingskontext in die Dateipom.xml. Wir sollten uns immer auf Maven Central beziehen, umthe latest version Abhängigkeiten zu erhalten:


    org.springframework
    spring-context
    5.1.4.RELEASE

3. @DependsOn

Wir sollten diese Annotation verwenden, um Bean-Abhängigkeiten anzugeben. Spring guarantees that the defined beans will be initialized before attempting an initialization of the current bean.

Nehmen wir an, wir haben einFileProcessor, das von einemFileReader undFileWriter abhängt. In diesem Fall solltenFileReader undFileWriter vorFileProcessor initialisiert werden.

4. Aufbau

Die Konfigurationsdatei ist eine reine Java-Klasse mit der Anmerkung@Configuration:

@Configuration
@ComponentScan("com.example.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 specifies its dependencies with @DependsOn. Wir können auchComponent mit@DependsOn: versehen

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

5. Verwendungszweck

Erstellen wir eine KlasseFile. Jede der Beans aktualisiert den Text innerhalb vonFile. FileReader aktualisiert es als gelesen. FileWriter aktualisiert es als Schreibvorgang undFileProcessor aktualisiert den Text als verarbeitet:

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

5.1. Fehlende Abhängigkeit

Bei fehlender Abhängigkeit wirft Spring einBeanCreationException mit einer Basisausnahme vonNoSuchBeanDefinitionException. Lesen Sie mehr überNoSuchBeanDefinitionExceptionhere.

Zum Beispiel hängt die Bean vondummyFileProcessorvon der Bean vondummyFileWriterab. DadummyFileWriter nicht existiert, wirdBeanCreationException: ausgelöst

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

5.2. Zirkuläre Abhängigkeit

In diesem Fall wirdBeanCreationException ausgelöst und hervorgehoben, dass die Beans eine zirkuläre Abhängigkeit haben:

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

Circular dependencies can happen if a bean has an eventual dependency on itself, einen Kreis erstellen:

Bean1 -> Bean4 -> Bean6 -> Bean1

6. Wichtige Punkte

Schließlich gibt es einige Punkte, auf die wir bei der Verwendung der Annotation von@DependsOnachten sollten:

  • Bei Verwendung von@DependsOn, müssen wir das Scannen von Komponenten verwenden

  • Wenn eine mitDependsOn-annotierte Klasse über XML deklariert wird, werden die Annotationsmetadaten vonDependsOnignoriert

7. Fazit

@DependsOn wird besonders nützlich, wenn Systeme mit komplexen Abhängigkeitsanforderungen erstellt werden.

Es erleichtert die Abhängigkeitsinjektion und stellt sicher, dass Spring die gesamte Initialisierung der erforderlichen Beans erledigt hat, bevor unsere abhängige Klasse geladen wird.

Wie immer kann der Codeover on GitHub gefunden werden.