BeanFactory和ApplicationContext的区别和联系


BeanFactory

BeanFactory提供了Spring ioC容器的基本功能API,它抽象出了用于与Spring其他组件或是第三方框架交互集成的规范,BeanFactory默认的实现类DefaultListableBeanFactoryGenericApplicationContext容器核心委托实现(ApplicationContext接口继承BeanFactory,但是BeanFactory接口主要还是通过代理DefaultListableBeanFactory来进行实现)

BeanFactory相关的接口(比如 BeanFactoryAware, InitializingBean, DisposableBean) 都是与其他框架集成的关键点,即使不通过注解或是反射,也能非常有效让其他框架与ioC容器交互,

BeanFactory的核心API和DefaultListableBeanFactory实现类并没有约定使用的配置格式或者任何的注解。都是通过扩展接口进行实现(比如: XmlBeanDefinitionReader 读取XMLbean定义 、 AutowiredAnnotationBeanPostProcessor负责处理@Autowire注解) ,并且所有的bean定义都是通过BeanDefinition接口表述和使用,这也是使得Spring ioC容器灵活性和扩展性强的原因。

BeanFactory还是 ApplicationContext

正常情况下,开发任何应用都应该使用ApplicationContextGenericApplicationContext以及它的子类AnnotationConfigApplicationContext作为主要的ApplicationContext实现。Spring的容器会做一些核心工作:加载配置文件、出发类路径扫描,注册bean定义等。

ApplicationContext包含了BeanFactory的所有功能,所以通常来说是使用ApplicationContext来进行构建应用,而不是使用BeanFactory,除了需要完全控制bean的处理流程这种场景。

除此之外,许多核心容器扩展的功能,比如:注解处理、AOP代理、 BeanPostProcessor扩展点,如果使用DefaultListableBeanFactory,像上述的BeanPostProcessor后置处理器不会被自动检测和激活使用。

BeanFactoryApplicationContext对比表:

特性BeanFactoryApplicationContext
Bean 实例化和装配YesYes
bean生命周期交互NoYes
自动注册 BeanPostProcessorNoYes
自动注册 BeanFactoryPostProcessorNoYes
获取 MessageSource (进行国际化)NoYes
ApplicationEvent 事件发布机制NoYes

如果需要给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中的重要性


文章作者: Ubi-potato
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ubi-potato !
评论
  目录