知識庫 / Spring RSS 訂閱

使用@DependsOn註解控制Bean創建順序

Spring
HongKong
9
01:46 PM · Dec 06 ,2025

1. 概述

Spring 默認管理 Bean 的生命週期並安排其初始化順序。

但是,我們可以根據需要進行自定義。 我們可以選擇使用 SmartLifeCycle 接口或使用 @DependsOn 註解來管理初始化順序。

本教程將探討 @DependsOn 註解及其在 Bean 缺失、循環依賴或僅僅需要一個 Bean 在另一個 Bean 之前初始化時的行為。

2. <em @DependsOn>

我們應該使用此註解來指定 Bean 依賴關係。 Spring 保證在嘗試當前 Bean 初始化之前,已定義的 Bean 已經被初始化。

例如,我們有一個 FileProcessor,它依賴於 FileReaderFileWriter。在這種情況下,FileReaderFileWriter 應該在 FileProcessor 初始化之前被初始化。

3. 配置

配置文件是一個純 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

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

4. 使用方法

讓我們創建一個名為 <em File</em> 的類。每個 Bean 都更新 <em File</em> 中的文本。<em FileReader</em> 在讀取時進行更新,<em FileWriter</em> 在寫入時進行更新,<em FileProcessor</em> 在處理文本時進行更新:

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

4.1. 缺失依賴

如果缺少依賴,Spring 會拋出 <em>BeanCreationException</em> 異常,其基礎異常是 <em>NoSuchBeanDefinitionException</em>。 更多關於 <em>NoSuchBeanDefinitionException</em> 的信息,請參考這裏。

例如,<em>dummyFileProcessor</em> bean 依賴於 <em>dummyFileWriter</em> bean。 由於 <em>dummyFileWriter</em> 不存在,因此它會拋出 <em>BeanCreationException</em>

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

4.2. 循環依賴

此外,在這種情況下,它會拋出 BeanCreationException,並指出這些 Bean 之間存在循環依賴關係:

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

循環依賴可能發生在 Bean 對自身產生最終依賴時,從而形成循環

Bean1 -> Bean4 -> Bean6 -> Bean1

5. 關鍵要點

請在使用 <em data-language="DependsOn">@DependsOn</em> 註解時注意以下幾點:

  • 在使用 <em data-language="DependsOn">@DependsOn</em> 註解時,必須使用組件掃描。
  • 如果通過 XML 聲明的 <em data-language="DependsOn">@DependsOn</em> 註解化的類,則忽略 <em data-language="DependsOn">@DependsOn</em> 註解的元數據。

6. 結論

@DependsOn 在構建具有複雜依賴要求的系統時尤其有用。

它促進了依賴注入,確保 Spring 會在加載我們的依賴類之前,已處理所有必需 Bean 的初始化。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.