BeanFactory
API
BeanFactory
API 為 Spring 的 IoC 功能提供了底層基礎。其特定契約主要用於與 Spring 的其他部分和相關的第三方框架整合,而其 DefaultListableBeanFactory
實作是較高層級 GenericApplicationContext
容器中的主要委派。
BeanFactory
和相關介面(例如 BeanFactoryAware
、InitializingBean
、DisposableBean
)是其他框架元件的重要整合點。由於不需要任何註解甚至反射,它們允許容器及其元件之間進行非常有效率的互動。應用程式層級的 Bean 可以使用相同的回呼介面,但通常更偏好宣告式相依性注入,可以透過註解或程式化組態。
請注意,核心 BeanFactory
API 層級及其 DefaultListableBeanFactory
實作不會對組態格式或要使用的任何元件註解做出假設。所有這些風格都是透過擴充功能(例如 XmlBeanDefinitionReader
和 AutowiredAnnotationBeanPostProcessor
)引入的,並以共用的 BeanDefinition
物件作為核心元資料表示形式進行操作。這是使 Spring 容器如此彈性和可擴充的本質。
BeanFactory
或 ApplicationContext
?
本節說明 BeanFactory
和 ApplicationContext
容器層級之間的差異,以及對啟動的影響。
您應該使用 ApplicationContext
,除非您有充分的理由不這樣做,GenericApplicationContext
及其子類別 AnnotationConfigApplicationContext
是自訂啟動的常用實作。這些是 Spring 核心容器的主要進入點,適用於所有常見目的:載入組態檔、觸發類別路徑掃描、以程式設計方式註冊 Bean 定義和註解類別,以及(自 5.0 起)註冊功能性 Bean 定義。
由於 ApplicationContext
包含 BeanFactory
的所有功能,因此通常建議使用 ApplicationContext
而不是純粹的 BeanFactory
,除非在需要完全控制 Bean 處理的情況下。在 ApplicationContext
(例如 GenericApplicationContext
實作)中,會依慣例偵測到幾種 Bean(也就是說,依 Bean 名稱或 Bean 類型 — 特別是後處理器),而純粹的 DefaultListableBeanFactory
對任何特殊 Bean 都持不可知論的態度。
對於許多擴充的容器功能,例如註解處理和 AOP 代理,BeanPostProcessor
擴充點至關重要。如果您僅使用純粹的 DefaultListableBeanFactory
,則預設情況下不會偵測和啟動此類後處理器。這種情況可能會令人困惑,因為您的 Bean 組態實際上沒有任何問題。相反地,在這種情況下,需要透過額外的設定來完全啟動容器。
下表列出了 BeanFactory
和 ApplicationContext
介面和實作提供的功能。
功能 | BeanFactory |
ApplicationContext |
---|---|---|
Bean 實例化/組裝 |
是 |
是 |
整合生命週期管理 |
否 |
是 |
自動 |
否 |
是 |
自動 |
否 |
是 |
方便的 |
否 |
是 |
內建 |
否 |
是 |
若要使用 DefaultListableBeanFactory
明確註冊 Bean 後處理器,您需要以程式設計方式呼叫 addBeanPostProcessor
,如下列範例所示
-
Java
-
Kotlin
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
val factory = DefaultListableBeanFactory()
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(AutowiredAnnotationBeanPostProcessor())
factory.addBeanPostProcessor(MyBeanPostProcessor())
// now start using the factory
若要將 BeanFactoryPostProcessor
應用於純粹的 DefaultListableBeanFactory
,您需要呼叫其 postProcessBeanFactory
方法,如下列範例所示
-
Java
-
Kotlin
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// bring in some property values from a Properties file
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// now actually do the replacement
cfg.postProcessBeanFactory(factory);
val factory = DefaultListableBeanFactory()
val reader = XmlBeanDefinitionReader(factory)
reader.loadBeanDefinitions(FileSystemResource("beans.xml"))
// bring in some property values from a Properties file
val cfg = PropertySourcesPlaceholderConfigurer()
cfg.setLocation(FileSystemResource("jdbc.properties"))
// now actually do the replacement
cfg.postProcessBeanFactory(factory)
在兩種情況下,明確的註冊步驟都不方便,這就是為什麼在 Spring 支援的應用程式中,各種 ApplicationContext
變體比純粹的 DefaultListableBeanFactory
更受歡迎的原因,尤其是在典型的企業設定中,依賴 BeanFactoryPostProcessor
和 BeanPostProcessor
實例來擴充容器功能時。
|