BeanFactory API

BeanFactory API 为 Spring 的 IoC 功能提供了底层基础。它的具体契约主要用于与 Spring 的其他部分以及相关的第三方框架集成,并且它的 DefaultListableBeanFactory 实现是更高级别 GenericApplicationContext 容器中的关键委托。BeanFactory 和相关接口(例如 BeanFactoryAwareInitializingBeanDisposableBean)是其他框架组件的重要集成点。通过不要求任何注解甚至反射,它们允许容器及其组件之间进行非常高效的交互。应用级别的 bean 可以使用相同的回调接口,但通常更喜欢声明式依赖注入,无论是通过注解还是通过编程配置。请注意,核心 BeanFactory API 级别及其 DefaultListableBeanFactory 实现不对要使用的配置格式或任何组件注解做任何假设。所有这些特性都通过扩展(例如 XmlBeanDefinitionReaderAutowiredAnnotationBeanPostProcessor)引入,并以共享的 BeanDefinition 对象作为核心元数据表示进行操作。这就是 Spring 容器如此灵活和可扩展的精髓所在。

BeanFactory 还是 ApplicationContext

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

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

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

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

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

Table 1. 功能矩阵
功能 BeanFactory ApplicationContext

Bean 实例化/装配

集成生命周期管理

自动 BeanPostProcessor 注册

自动 BeanFactoryPostProcessor 注册

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

内置 ApplicationEvent 发布机制

要将 bean 后处理器显式注册到 DefaultListableBeanFactory,您需要以编程方式调用 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 后处理器的概念变成了纯粹的内部容器细节。