对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

The BeanFactory API

The BeanFactory API 提供了 Spring 的 IoC 功能的基础。 其具体的契约主要在与其他 Spring 部分和相关第三方框架的集成中使用, 其 DefaultListableBeanFactory 实现是更高层次 GenericApplicationContext 容器中的关键委托。spring-doc.cadn.net.cn

BeanFactory 和相关接口(如 BeanFactoryAwareInitializingBeanDisposableBean)是其他框架组件的重要集成点。 通过不需要任何注解甚至反射,它们允许容器与其组件之间进行高效的交互。应用层的 bean 可以使用相同的回调接口,但通常更倾向于通过注解或编程配置进行声明式依赖注入。spring-doc.cadn.net.cn

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

BeanFactory 还是 ApplicationContext

本节解释了 BeanFactoryApplicationContext 容器级别之间的区别以及对引导过程的影响。spring-doc.cadn.net.cn

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

由于ApplicationContext包含了BeanFactory的所有功能,因此通常推荐使用它,而不是普通的BeanFactory,除非需要对bean处理有完全的控制。在ApplicationContext(例如GenericApplicationContext实现)中,通过约定(即通过bean名称或bean类型——特别是后处理器)检测到几种类型的beans,而普通的DefaultListableBeanFactory则不关心任何特殊的beans。spring-doc.cadn.net.cn

对于许多扩展的容器功能,如注解处理和AOP代理, BeanPostProcessor 扩展点 是必不可少的。 如果你只使用普通的 DefaultListableBeanFactory,那么这些后处理器默认情况下不会 被检测和激活。这种情况可能会让人感到困惑,因为你的 bean 配置实际上并没有问题。相反,在这种情况下, 容器需要通过额外的设置才能完全启动。spring-doc.cadn.net.cn

以下表格列出了BeanFactoryApplicationContext接口及实现提供的功能。spring-doc.cadn.net.cn

表1. 功能矩阵
特性 BeanFactory ApplicationContext

Bean实例化/装配spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

集成生命周期管理spring-doc.cadn.net.cn

Nospring-doc.cadn.net.cn

spring-doc.cadn.net.cn

自动 BeanPostProcessor 注册spring-doc.cadn.net.cn

Nospring-doc.cadn.net.cn

spring-doc.cadn.net.cn

自动 BeanFactoryPostProcessor 注册spring-doc.cadn.net.cn

Nospring-doc.cadn.net.cn

spring-doc.cadn.net.cn

便捷的 MessageSource 访问(用于国际化)spring-doc.cadn.net.cn

Nospring-doc.cadn.net.cn

spring-doc.cadn.net.cn

内置 ApplicationEvent 发布机制spring-doc.cadn.net.cn

Nospring-doc.cadn.net.cn

spring-doc.cadn.net.cn

要显式地将一个 bean 后置处理器注册为 DefaultListableBeanFactory, 你需要调用 addBeanPostProcessor,如下例所示:spring-doc.cadn.net.cn

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 方法,如下例所示:spring-doc.cadn.net.cn

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 实例来实现典型企业设置中扩展容器功能时。spring-doc.cadn.net.cn

一个 AnnotationConfigApplicationContext 注册了所有常见的注解后处理器, 并通过配置注解(例如 @EnableTransactionManagement)可能在内部引入其他处理器。 在 Spring 基于注解的配置模型的抽象层面上, bean 后处理器的概念仅是容器内部的细节。spring-doc.cadn.net.cn