3.16.1 BeanFactory or ApplicationContext?
优先使用ApplicationContext
,除非你有一个很好的理由不这样做。
因为ApplicationContext
包括BeanFactory
的所有功能,和BeanFactory
相比更值得推荐,除了一些特定的场景,比如,在资源受限的设备上运行的内嵌的应用,这些设备非常关注内存消耗。无论如何,对于大多数的企业级应用和系统,ApplicationContext
都是首选。Spring使用了的大量的BeanPostProcessor
扩展点 (以实现代理等)。如果你只使用一个简单的BeanFactory,大量的功能将失效,比如:transactions 和AOP ,至少得多一些额外的处理。这种情况可能会令人困惑,因为没有什么是实际上错误的配置。
下表列出了“BeanFactory”和“ApplicationContext”接口和实现提供的功能。
Table 3.9. Feature Matrix
Feature | BeanFactory |
ApplicationContext |
---|---|---|
bean实例化和组装 | Yes | Yes |
自动注册BeanPostProcessor |
No | Yes |
自动注册BeanFactoryPostProcessor |
No | Yes |
便利的消息资源访问(用于i18n) | No | Yes |
ApplicationEvent 的发布 |
No | Yes |
要使用BeanFactory实现显式地注册bean后置处理器post-processor,你得需要编写如下代码:
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);
在这两种情况下显示注册步骤非常不便,这就是为什么推荐使用ApplicationContext
的原因之一,就是为了方便的使用BeanFactoryPostProcessors
和BeanPostProcessors
。这些机制实现了一些非常重要的功能,例如属性占位符替换和AOP。