BeanFactory API

BeanFactory API 为 Spring 的 IoC 功能提供了底层基础。它的特定契约主要用于与 Spring 的其他部分和相关的第三方框架集成,其DefaultListableBeanFactory实现是更高级别GenericApplicationContext容器中的一个关键委托。

BeanFactory 和相关的接口(例如 BeanFactoryAwareInitializingBeanDisposableBean)是其他框架组件的重要集成点。由于不需要任何注解甚至反射,它们允许容器及其组件之间进行非常有效的交互。应用程序级 Bean 可以使用相同的回调接口,但通常更喜欢声明性依赖注入,无论是通过注解还是通过编程配置。

请注意,核心BeanFactory API级别及其DefaultListableBeanFactory实现不会对要使用的配置格式或任何组件注解做出假设。所有这些风格都是通过扩展(例如XmlBeanDefinitionReaderAutowiredAnnotationBeanPostProcessor)引入的,并以共享BeanDefinition对象作为核心元数据表示进行操作。这就是使 Spring 容器如此灵活和可扩展的本质。

BeanFactory还是ApplicationContext

本节解释了BeanFactoryApplicationContext容器级别之间的区别以及对引导的影响。

除非您有充分的理由不这样做,否则应使用ApplicationContextGenericApplicationContext及其子类AnnotationConfigApplicationContext是自定义引导的常用实现。对于所有常见目的,它们是 Spring 核心容器的主要入口点:加载配置文件,触发类路径扫描,以编程方式注册 Bean 定义和带注解的类,以及(从 5.0 开始)注册函数式 Bean 定义。

因为ApplicationContext包含BeanFactory的所有功能,所以通常建议使用它而不是普通的BeanFactory,除非需要完全控制 Bean 处理。在ApplicationContext(例如GenericApplicationContext实现)中,几种类型的 Bean 是通过约定检测的(即,通过 Bean 名称或 Bean 类型——特别是后处理器),而普通的DefaultListableBeanFactory则不了解任何特殊的 Bean。

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

下表列出了BeanFactoryApplicationContext接口和实现提供的功能。

表1. 功能矩阵
功能 BeanFactory ApplicationContext

Bean实例化/连接

集成的生命周期管理

自动BeanPostProcessor注册

自动BeanFactoryPostProcessor注册

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

内置ApplicationEvent发布机制

要显式地向DefaultListableBeanFactory注册 Bean 后处理器,需要以编程方式调用addBeanPostProcessor,如下例所示

  • 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

要将BeanFactoryPostProcessor应用于普通的DefaultListableBeanFactory,需要调用其postProcessBeanFactory方法,如下例所示

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

在这两种情况下,显式注册步骤都不方便,这就是为什么在 Spring 支持的应用程序中,各种ApplicationContext变体比普通的DefaultListableBeanFactory更受欢迎的原因,尤其是在依赖于BeanFactoryPostProcessorBeanPostProcessor实例来在典型的企业设置中扩展容器功能时。

AnnotationConfigApplicationContext注册了所有常见的注解后处理器,并可能通过配置注解(例如@EnableTransactionManagement)在幕后引入额外的处理器。在 Spring 基于注解的配置模型的抽象级别上,Bean 后处理器的概念变成了一个纯粹的内部容器细节。