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 的所有功能,所以除了需要完全控制 bean 處理的場景外,通常建議使用它而不是普通的 BeanFactory。在 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 例項來實現擴充套件容器功能時。
|
|