知識庫 / Spring RSS 訂閱

Spring Bean 名稱

Spring
HongKong
11
12:31 PM · Dec 06 ,2025

1. 概述

命名 Spring Bean 在我們有相同類型的多個實現時非常有用。這是因為如果我們的 Bean 沒有唯一的名稱,Spring 將會變得模糊,無法正確地注入 Bean。

通過對 Bean 的命名進行控制,我們可以告訴 Spring 我們想要注入到目標對象中的哪個 Bean。

在本文中,我們將討論 Spring Bean 命名策略,並探討如何為單個類型的 Bean 賦予多個名稱。

2. 默認 Bean 命名策略

Spring 提供了多種註解來創建 Bean。我們可以使用這些註解在不同級別。例如,我們可以將一些註解放置在 Bean 類上,另一些註解放置在創建 Bean 的方法上。

首先,讓我們看看 Spring 的默認 Bean 命名策略在實踐中的應用。當僅指定註解而沒有提供任何值,Spring 如何命名我們的 Bean?

2.1 類級別標註

我們先來看一下用於類級別的默認命名策略。為了命名一個 Bean,Spring 會使用類名並將其第一個字母轉換為小寫

下面我們來看一個例子:

@Service
public class LoggingService {
}

這裏,Spring 為類 LoggingService 創建一個 Bean,並使用名稱 “loggingService” 註冊它。

這種默認命名策略也適用於所有用於創建 Spring Bean 的類級別註解,例如 @Component, @Service, 和 @Controller

2.2. 方法級別註解

Spring 提供了諸如 @Bean@Qualifier 這樣的註解,用於在方法上進行 Bean 創建。

讓我們通過一個示例來理解 @Bean 註解的默認命名策略:

@Configuration
public class AuditConfiguration {
    @Bean
    public AuditService audit() {
          return new AuditService();
    }
}

在配置類中,Spring 會將類型為 AuditService 的 Bean 註冊為名為 “audit” 的 Bean,這是因為 當我們使用 @Bean 註解在方法上時,Spring 會使用該方法名作為 Bean 的名稱

我們還可以使用 @Qualifier 註解在方法上,並在下面看到一個示例。

3. 自定義 Bean 名稱

當我們在同一個 Spring 上下文中需要創建多個相同類型的 Bean 時,我們可以為這些 Bean 分配自定義名稱,並使用這些名稱進行引用。

讓我們看看如何為我們的 Spring Bean 分配自定義名稱:

@Component("myBean")
public class MyCustomComponent {
}

本次,Spring 將創建一個類型為 MyCustomComponent 的 Bean,名稱為 “myBean“。

由於我們明確指定了 Bean 的名稱,Spring 將使用這個名稱,進而可以用來引用或訪問該 Bean。

類似於 @Component(“myBean”),我們可以使用其他註解(如 @Service(“myService”)@Controller(“myController”)@Bean(“myCustomBean”))來指定名稱,然後 Spring 將以該名稱註冊該 Bean。

4. 使用 @Bean@Qualifier 命名 Bean

4.1. 使用 @Bean 指定值

正如前面所見,@Bean 註解應用於方法級別,默認情況下 Spring 使用方法名作為 Bean 名稱。

此默認 Bean 名稱可以被覆蓋——我們可以使用 @Bean 註解指定值:

@Configuration
public class MyConfiguration {
    @Bean("beanComponent")
    public MyCustomComponent myComponent() {
        return new MyCustomComponent();
    }
}

在這種情況下,要獲取類型為 MyCustomComponent 的 Bean,我們可以通過使用名稱“beanComponent”來引用該 Bean。

Spring 的 @Bean 註解通常在配置類的方法中聲明。它可以通過直接調用同一類中的其他 @Bean 方法來引用它們。

4.2. 使用 @Qualifier</em/> 指定 Bean 名稱

我們可以使用 @Qualifier</em/> 註解來為 Bean 指定名稱。

首先,讓我們創建一個接口 Animal</em/>,該接口將被多個類實現:

public interface Animal {
    String name();
}

現在,讓我們定義一個實現類 Cat,併為其添加 @Qualifier 註解,其值為 “cat”:

@Component 
@Qualifier("cat") 
public class Cat implements Animal { 
    @Override 
     public String name() { 
        return "Cat"; 
     } 
}

讓我們添加另一個 Animal 的實現,並對其進行註釋,使用 @Qualifier 註解,以及值為 "dog“:

@Component
@Qualifier("dog")
public class Dog implements Animal {
    @Override
    public String name() {
        return "Dog";
    }
}

現在,讓我們編寫一個類 PetShow,其中可以注入兩個不同的 Animal 實例:

@Service 
public class PetShow { 
    private final Animal dog; 
    private final Animal cat; 

    public PetShow (@Qualifier("dog")Animal dog, @Qualifier("cat")Animal cat) { 
      this.dog = dog; 
      this.cat = cat; 
    }
    public Animal getDog() { 
      return dog; 
    }
    public Animal getCat() { 
      return cat; 
    }
}

<em >Pet</em ><em >Show</em >> 類中,我們通過在構造參數上使用 <em >@Qualifier</em >> 註解,並指定 qualified bean 名稱在 value 屬性中的值,來注入了 <em >Animal</em >> 類型的實現。每當我們使用這個 qualified 名稱時,Spring 都會將具有該 qualified 名稱的 bean 注入到目標 bean 中。

5. 驗證 Bean 名稱

我們已經看到了各種示例,用於為 Spring Bean 命名。現在的問題是,我們如何驗證或測試這些命名?

讓我們來看一個單元測試,以驗證其行為:

@ExtendWith(SpringExtension.class)
public class SpringBeanNamingUnitTest {
    private AnnotationConfigApplicationContext context;
    
    @BeforeEach
    void setUp() {
        context = new AnnotationConfigApplicationContext();
        context.scan("com.baeldung.springbean.naming");
        context.refresh();
    }
    
    @Test
    void givenMultipleImplementationsOfAnimal_whenFieldIsInjectedWithQualifiedName_thenTheSpecificBeanShouldGetInjected() {
        PetShow petShow = (PetShow) context.getBean("petShow");
        assertThat(petShow.getCat().getClass()).isEqualTo(Cat.class);
        assertThat(petShow.getDog().getClass()).isEqualTo(Dog.class);
    }

在本次 JUnit 測試中,我們將在 setUp 方法中初始化 AnnotationConfigApplicationContext,用於獲取 Bean。

然後,我們使用標準斷言來驗證 Spring Bean 的類。

6. 結論

在本文中,我們探討了默認和自定義的 Spring Bean 命名策略。

我們還學習了自定義 Spring Bean 命名在需要管理相同類型的多個 Bean 的用例中的實用性。

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

發佈 評論

Some HTML is okay.