@DependsOnアノテーションを使用したBean作成順序の制御

@DependsOnアノテーションを使用したBean作成順序の制御

1. 概要

デフォルトでは、SpringはBeanのライフサイクルを管理し、Beanの初期化順序を調整します。

ただし、ニーズに基づいてカスタマイズすることはできます。 We can choose either the SmartLifeCycle interface or the @DependsOn annotation for managing initialization order

このチュートリアルでは、@DependsOnアノテーションと、Beanまたはcircular dependencyが欠落している場合のその動作について説明します。 または、単に1つのBeanを別のBeanの前に初期化する必要がある場合。

2. メーベン

まず、スプリングコンテキストの依存関係をpom.xmlファイルにインポートしましょう。 依存関係のthe latest versionについては、常にMavenCentralを参照する必要があります。


    org.springframework
    spring-context
    5.1.4.RELEASE

3. @DependsOn

Beanの依存関係を指定するには、この注釈を使用する必要があります。 Spring guarantees that the defined beans will be initialized before attempting an initialization of the current bean.

FileReaderFileWriterに依存するFileProcessorがあるとしましょう。 この場合、FileReaderFileWriterFileProcessorの前に初期化する必要があります。

4. 設定

構成ファイルは、@Configurationアノテーションが付いた純粋なJavaクラスです。

@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 @DependsOnComponent@DependsOn:で注釈を付けることもできます

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

5. 使用法

1つのクラスFileを作成しましょう。 各Beanは、File内のテキストを更新します。 FileReaderはそれを既読として更新します。 FileWriterは書き込みとして更新し、FileProcessorは処理済みとしてテキストを更新します。

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

5.1. 不足している依存関係

依存関係が欠落している場合、SpringはNoSuchBeanDefinitionExceptionの基本例外を除いてBeanCreationExceptionをスローします。 NoSuchBeanDefinitionExceptionhereの詳細をご覧ください。

たとえば、dummyFileProcessor BeanはdummyFileWriterBeanに依存します。 dummyFileWriterが存在しないため、BeanCreationException:をスローします

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

5.2. 循環依存

また、この場合、BeanCreationExceptionをスローし、Beanが循環依存関係にあることを強調表示します。

@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、円を作成します:

Bean1 -> Bean4 -> Bean6 -> Bean1

6. キーポイント

最後に、@DependsOnアノテーションを使用する際に注意する必要のあるポイントがいくつかあります。

  • @DependsOn,を使用している間、コンポーネントスキャンを使用する必要があります

  • DependsOnアノテーション付きクラスがXMLを介して宣言されている場合、DependsOnアノテーションメタデータは無視されます

7. 結論

@DependsOnは、複雑な依存関係要件を持つシステムを構築するときに特に役立ちます。

依存性注入を容易にし、依存クラスをロードする前に、Springが必要なBeanのすべての初期化を処理するようにします。

いつものように、コードはover on GitHubで見つけることができます。