BeanFactory
API
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 类型 — 特别是后处理器)检测到几种类型的 beans,而普通的 DefaultListableBeanFactory
对任何特殊的 beans 都是无关的。
对于许多扩展容器特性,例如注解处理和 AOP 代理,BeanPostProcessor 扩展点 是至关重要的。如果您仅使用普通的 DefaultListableBeanFactory
,那么这些后处理器默认不会被检测和激活。这种情况可能会令人困惑,因为您的 bean 配置实际上没有任何问题。相反,在这种情况下,容器需要通过额外的设置进行完全引导。
下表列出了 BeanFactory
和 ApplicationContext
接口及其实现所提供的特性。
表 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
更受欢迎,特别是在典型企业设置中依赖 BeanFactoryPostProcessor
和 BeanPostProcessor
实例以扩展容器功能时。
一个 AnnotationConfigApplicationContext
注册了所有常见的注解后处理器,并且可能通过配置注解(例如 @EnableTransactionManagement
)在内部引入额外的处理器。在 Spring 的基于注解的配置模型的抽象层面上,bean 后处理器的概念仅仅是一个内部容器细节。