基本概念:@Bean@Configuration

Spring 的 Java 組態支援中的核心構件是 @Configuration 註解類別和 @Bean 註解方法。

@Bean 註解用於指示方法實例化、設定和初始化要由 Spring IoC 容器管理的新物件。對於熟悉 Spring 的 <beans/> XML 組態的人來說,@Bean 註解扮演的角色與 <bean/> 元素相同。您可以將 @Bean 註解方法與任何 Spring @Component 一起使用。但是,它們最常與 @Configuration Bean 一起使用。

使用 @Configuration 註解類別表示其主要目的是作為 Bean 定義的來源。此外,@Configuration 類別允許透過呼叫相同類別中的其他 @Bean 方法來定義 Bean 之間的相依性。最簡單的 @Configuration 類別如下所示

  • Java

  • Kotlin

@Configuration
public class AppConfig {

	@Bean
	public MyServiceImpl myService() {
		return new MyServiceImpl();
	}
}
@Configuration
class AppConfig {

	@Bean
	fun myService(): MyServiceImpl {
		return MyServiceImpl()
	}
}

上述 AppConfig 類別等同於以下 Spring <beans/> XML

<beans>
	<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
具有或不具有 @Bean 方法之間本機呼叫的 @Configuration 類別?

在常見情況下,@Bean 方法應在 @Configuration 類別中宣告,以確保應用完整的組態類別處理,並且跨方法參考因此重新導向到容器的生命週期管理。這可以防止相同的 @Bean 方法意外地透過常規 Java 方法呼叫來調用,這有助於減少難以追蹤的細微錯誤。

@Bean 方法在未使用 @Configuration 註解的類別中宣告時 - 或者當宣告 @Configuration(proxyBeanMethods=false) 時 - 它們被稱為在「輕量」模式下處理。在這種情況下,@Bean 方法實際上是一種通用工廠方法機制,沒有特殊的執行時期處理(也就是說,沒有為它產生 CGLIB 子類別)。對此類方法的自訂 Java 呼叫不會被容器攔截,因此行為就像常規方法呼叫一樣,每次都建立一個新實例,而不是為給定的 Bean 重複使用現有的單例(或作用域)實例。

因此,沒有執行時期代理的類別上的 @Bean 方法根本不適合宣告 Bean 之間的相依性。相反,它們預期在其包含元件的欄位上操作,並且可選地在工廠方法可能宣告以接收自動裝配協作者的引數上操作。因此,此類 @Bean 方法永遠不需要調用其他 @Bean 方法;每個此類呼叫都可以透過工廠方法引數來表示。這裡的正面副作用是不必在執行時期應用 CGLIB 子類別化,從而減少了額外負擔和佔用空間。

@Bean@Configuration 註解將在以下各節中深入討論。但是,首先,我們介紹使用基於 Java 的組態建立 Spring 容器的各種方法。