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的所有功能,所以通常建议使用它而不是纯BeanFactory,除非需要对bean处理具有完全控制。在ApplicationContext(如GenericApplicationContext实现)中,按照约定检测到几种类型的bean(即,按照bean名称或bean类型 - 特别是后处理器),而纯DefaultListableBeanFactory对任何特殊bean都是不可知的。

对于许多扩展的容器功能,如注解处理和AOP代理,BeanPostProcessor扩展点至关重要。如果仅使用纯DefaultListableBeanFactory,则此类后处理器不会被默认检测和激活。这种情况可能会令人困惑,因为您的bean配置实际上没有任何问题。相反,在这种情况下,需要通过额外的设置完全引导容器。

以下表列出了BeanFactory和ApplicationContext接口及其实现提供的功能。

表1. 功能矩阵
功能 BeanFactory ApplicationContext

Bean实例化/装配

集成生命周期管理

自动BeanPostProcessor注册

自动BeanFactoryPostProcessor注册

方便的MessageSource访问(用于国际化)

内置ApplicationEvent发布机制

  • 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

  • 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)