`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` 的所有功能,因此通常推荐使用 `ApplicationContext` 而非纯粹的 `BeanFactory`,除非在需要完全控制 bean 处理的场景下。在 `ApplicationContext` 中(例如 `GenericApplicationContext` 实现),通过约定(即按 bean 名称或按 bean 类型——特别是后处理器)检测到几种类型的 bean,而纯粹的 `DefaultListableBeanFactory` 对任何特殊 bean 都是不可知的。
对于许多扩展的容器功能,例如注解处理和 AOP 代理,BeanPostProcessor
扩展点至关重要。如果您只使用纯粹的 `DefaultListableBeanFactory`,此类后处理器默认情况下不会被检测和激活。这种情况可能会令人困惑,因为您的 bean 配置实际上没有问题。相反,在这种情况下,需要通过附加设置来完全引导容器。
下表列出了 `BeanFactory` 和 `ApplicationContext` 接口和实现提供的功能。
功能 | 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` 更受欢迎,特别是在依赖 `BeanFactoryPostProcessor` 和 `BeanPostProcessor` 实例以实现典型企业设置中的扩展容器功能时。
一个 `AnnotationConfigApplicationContext` 注册了所有常见的注解后处理器,并且可以通过配置注解(例如 `@EnableTransactionManagement`)在底层引入额外的处理器。在 Spring 基于注解的配置模型的抽象层面,bean 后处理器的概念仅仅是一个内部容器细节。 |