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-web 和 spring-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。