BeanFactory
是Spring IoC功能的潛在基礎,但是現在BeanFactory
一般僅僅用於直接集成第三方的框架,對於大多數的Spring用戶來說,BeanFactory
已經算是一個歷史了。BeanFactory
以及其相關的接口,包括BeanFactoryAware
,InitializingBean
,DisposableBean
,出於跟大量第三方框架兼容的問題,仍然存在。因爲很多時候,第三方組件還不能使用形如@PostConstruct
或者@PreDestroy
這類的註解,爲了繼續支持JDK1.4以及避免依賴於JSR-250標準。
下面將描述BeanFactory
和ApplicationContext
之間的一些異同以及如何通過典型的單例查找訪問IoC容器。
BeanFactory
還是 ApplicationContext
?
最好還是使用ApplicationContext
除非真的有不得不使用BeanFactory
的理由。
因爲ApplicationContext
包含了BeanFactory
的所有功能,所以它更優於BeanFactory
。只有少數情況,比如嵌入式應用環境中,運行應用的設備資源受限,內存要求更爲嚴格,僅僅差幾k幾十k內存開銷都會對應用產生影響的情況,才需要權衡是否使用BeanFactory
。所以,在絕大多數的典型情況之中,開發者肯定還是使用ApplicationContext
最好。Spring在BeanPostProcessor
這個擴展點上是重度用戶,如果開發者僅僅使用BeanFactory
的話,相當多的功能,諸如事務,AOP都將不會生效。這個時候,就會讓人很疑惑,因爲配置都是正確的。
下表列出了所有BeanFactory
和ApplicationContext
接口和實現的一些特性:
Feature | BeanFactory |
ApplicationContext |
---|---|---|
Bean的實例化和裝載 | 支持 | 支持 |
自動的BeanPostProcessor 註冊 |
不支持 | 支持 |
自動的BeanFactoryPostProcessor 註冊 |
不支持 | 支持 |
MessageSource 國際化 |
不支持 | 支持 |
ApplicationEvent 的發佈 |
不支持 | 支持 |
如果是在BeanFactory
的實現下來註冊Bean的後置處理器的,需要寫如下的代碼:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
factory.addBeanPostProcessor(postProcessor);
// now start using the factory
如果是在BeanFactory
中明確的註冊一個BeanFactoryPostProcessor
的話,需要寫如下代碼:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// bring in some property values from a Properties file
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// now actually do the replacement
cfg.postProcessBeanFactory(factory);
可以看到,上面的兩種方式,Bean的註冊過程都是相當繁瑣的,這也是爲什麼要推薦使用ApplicationContext
而非BeanFactory
的原因。而且,尤其是在需要使用BeanFactoryPostProcessor
,BeanPostProcessor
以及佔位符替換,AOP等功能的時候,ApplicationContext
會比BeanFactory
更爲方便。