BeanFactory
BeanFactory
提供了Spring ioC容器的基本功能API,它抽象出了用于与Spring其他组件或是第三方框架交互集成的规范,BeanFactory
默认的实现类DefaultListableBeanFactory
是GenericApplicationContext
容器核心委托实现(ApplicationContext
接口继承BeanFactory
,但是BeanFactory
接口主要还是通过代理DefaultListableBeanFactory
来进行实现)
BeanFactory
相关的接口(比如 BeanFactoryAware
, InitializingBean
, DisposableBean
) 都是与其他框架集成的关键点,即使不通过注解或是反射,也能非常有效让其他框架与ioC容器交互,
BeanFactory
的核心API和DefaultListableBeanFactory
实现类并没有约定使用的配置格式或者任何的注解。都是通过扩展接口进行实现(比如: XmlBeanDefinitionReader
读取XMLbean定义 、 AutowiredAnnotationBeanPostProcessor
负责处理@Autowire
注解) ,并且所有的bean定义都是通过BeanDefinition
接口表述和使用,这也是使得Spring ioC容器灵活性和扩展性强的原因。
BeanFactory
还是 ApplicationContext
?
正常情况下,开发任何应用都应该使用ApplicationContext
,GenericApplicationContext
以及它的子类AnnotationConfigApplicationContext
作为主要的ApplicationContext
实现。Spring的容器会做一些核心工作:加载配置文件、出发类路径扫描,注册bean定义等。
ApplicationContext
包含了BeanFactory
的所有功能,所以通常来说是使用ApplicationContext
来进行构建应用,而不是使用BeanFactory
,除了需要完全控制bean的处理流程这种场景。
除此之外,许多核心容器扩展的功能,比如:注解处理、AOP代理、 BeanPostProcessor
扩展点,如果使用DefaultListableBeanFactory
,像上述的BeanPostProcessor后置处理器不会被自动检测和激活使用。
BeanFactory
和ApplicationContext
对比表:
特性 | BeanFactory | ApplicationContext |
---|---|---|
Bean 实例化和装配 | Yes | Yes |
bean生命周期交互 | No | Yes |
自动注册 BeanPostProcessor | No | Yes |
自动注册 BeanFactoryPostProcessor | No | Yes |
获取 MessageSource (进行国际化) | No | Yes |
ApplicationEvent 事件发布机制 | No | Yes |
如果需要给DefaultListableBeanFactory
注册后置处理器,需要手动调用其addBeanPostProcessor
方法:
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
通过DefaultListableBeanFactory
使用后置处理器需要手动调用postProcessBeanFactory
方法:
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);
通过上述代码,可以知道,通过原生的BeanFactory
需要手动“造轮子”才能完成一些ApplicationContext
具有的特性,但是BeanFactory
能完全掌控bean的处理流程,所以在没有特殊需求的场景下还是都是使用ApplicationContext
。
AnnotationConfigApplicationContext
具有所有的公共注解后置处理器,也能够处理一些额外的注解,比如:@EnableTransactionManagement
,由此可见后置处理器BeanPostProcessor
在Spring中的重要性