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 的所有功能,所以除了需要完全控制 bean 处理的场景外,通常建议使用它而不是普通的 BeanFactory。在 ApplicationContext(例如 GenericApplicationContext 实现)中,通过约定(即,通过 bean 名称或 bean 类型 — 特别是后处理器)检测到几种 bean,而普通的 DefaultListableBeanFactory 对任何特殊 bean 都是不可知的。
对于许多扩展容器功能,例如注解处理和 AOP 代理,BeanPostProcessor 扩展点至关重要。如果您只使用普通的 DefaultListableBeanFactory,则默认情况下不会检测到并激活此类后处理器。这种情况可能会令人困惑,因为您的 bean 配置实际上并没有任何问题。相反,在这种情况下,容器需要通过额外的设置来完全引导启动。
下表列出了 BeanFactory 和 ApplicationContext 接口及其实现提供的功能。
| 功能 | BeanFactory |
ApplicationContext |
|---|---|---|
Bean 实例化/装配 |
是 |
是 |
集成生命周期管理 |
否 |
是 |
自动 |
否 |
是 |
自动 |
否 |
是 |
便捷的 |
否 |
是 |
内置 |
否 |
是 |
要使用 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,尤其是在典型的企业设置中,依赖 BeanFactoryPostProcessor 和 BeanPostProcessor 实例来实现扩展容器功能时。
|
|