知識庫 / Spring RSS 訂閱

Spring 泛型 Bean 註冊

Spring
HongKong
4
02:24 PM · Dec 06 ,2025

1. 概述

Spring 5 提供了在應用程序上下文中支持函數式 Bean 註冊的功能。

簡單來説,這可以通過 registerBean() 方法的重載版本實現,該方法定義在 GenericApplicationContext 類中。

下面我們將通過一些示例來查看該功能的實際應用。

2. Maven 依賴

使用 Maven 設置 Spring 5 項目最快捷的方式是添加 <spring-boot-starter-parent> 依賴到 pom.xml 文件中。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
</parent>

我們還需要 spring-boot-starter-webspring-boot-starter-test 用於我們的示例,以便在 JUnit 測試中使用 Web 應用上下文:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

當然,Spring Boot並非使用新的函數式方式註冊 Bean 的必要條件。我們也可以直接添加 spring-core依賴項:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>6.0.13</version>
</dependency>

3. 功能 Bean 註冊

registerBean() API 可以接收兩個類型的函數式接口作為參數:

  • a Supplier 參數,用於創建對象
  • 一個 BeanDefinitionCustomizer vararg 參數,可用於向 BeanDefinition 提供一個或多個 lambda 表達式,以自定義 Bean;此接口包含一個 customize() 方法

首先,讓我們創建一個簡單的類定義,我們將使用它來創建 Bean:

public class MyService {
    public int getRandomNumber() {
        return new Random().nextInt(10);
    }
}

讓我們也添加一個 @SpringBootApplication 類,以便我們可以運行一個 JUnit 測試:

@SpringBootApplication
public class Spring5Application {
    public static void main(String[] args) {
        SpringApplication.run(Spring5Application.class, args);
    }
}

接下來,我們可以使用 @SpringBootTest 註解設置我們的測試類,從而創建一個 GenericWebApplicationContext 實例:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Spring5Application.class)
public class BeanRegistrationIntegrationTest {
    @Autowired
    private GenericWebApplicationContext context;
   
    //...
}

我們正在本示例中使用 GenericWebApplicationContext 類型,但任何類型的應用程序上下文都可以以相同的方式使用,以註冊一個 Bean。

讓我們看看如何使用 Lambda 表達式來註冊 Bean:

context.registerBean(MyService.class, () -> new MyService());

讓我們驗證我們現在是否可以檢索到該 Bean 並使用它:

MyService myService = (MyService) context.getBean("com.baeldung.functional.MyService"); 
 
assertTrue(myService.getRandomNumber() < 10);

我們可以從這個例子中看出,如果未明確定義 Bean 名稱,則它將從類名的小寫名稱中確定。相同的代碼片段也可以使用明確的 Bean 名稱:

context.registerBean("mySecondService", MyService.class, () -> new MyService());

接下來,讓我們看看如何通過在配置中添加 lambda 表達式來定製註冊一個 Bean:

context.registerBean("myCallbackService", MyService.class, 
  () -> new MyService(), bd -> bd.setAutowireCandidate(false));

這個論點是一個回調,我們可以使用它來設置 Bean 屬性,例如 autowire-candidate 標誌或 primary 標誌。

4. 結論

在本快速教程中,我們學習瞭如何使用函數式方式註冊 Bean。

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

發佈 評論

Some HTML is okay.