`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 例項化/連線 |
是 |
是 |
整合生命週期管理 |
否 |
是 |
自動 `BeanPostProcessor` 註冊 |
否 |
是 |
自動 `BeanFactoryPostProcessor` 註冊 |
否 |
是 |
方便地訪問 `MessageSource`(用於國際化) |
否 |
是 |
內建 `ApplicationEvent` 釋出機制 |
否 |
是 |
要將 bean 後處理器顯式註冊到 `DefaultListableBeanFactory`,您需要以程式設計方式呼叫 `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` 例項以實現典型企業設定中的擴充套件容器功能時。
一個 `AnnotationConfigApplicationContext` 註冊了所有常見的註解後處理器,並且可以透過配置註解(例如 `@EnableTransactionManagement`)在底層引入額外的處理器。在 Spring 基於註解的配置模型的抽象層面,bean 後處理器的概念僅僅是一個內部容器細節。 |