跳到主要内容
版本:7.0.3

BeanFactory API

Hunyuan 7b 中英对照 The BeanFactory API The BeanFactory API

BeanFactory API 为 Spring 的 IoC(控制反转)功能提供了基础。其具体的接口契约主要用于与 Spring 的其他部分及相关第三方框架的集成,而其 DefaultListableBeanFactory 实现则是更高级别的 GenericApplicationContext 容器中的关键委托组件。

BeanFactory 及相关接口(如 BeanFactoryAwareInitializingBeanDisposableBean)是其他框架组件的重要集成点。由于不需要任何注解甚至反射,它们允许容器与其组件之间进行非常高效的交互。应用级别的 Bean 可以使用相同的回调接口,但通常更倾向于使用声明式的依赖注入,无论是通过注解还是通过编程配置来实现。

请注意,核心的BeanFactory API级别及其DefaultListableBeanFactory实现并不对配置格式或将要使用的任何组件注解做出任何假设。所有这些扩展功能都是通过插件(如XmlBeanDefinitionReaderAutowiredAnnotationBeanPostProcessor)实现的,并且它们都操作作为核心元数据表示的共享BeanDefinition对象。这就是Spring容器如此灵活和可扩展的本质所在。

BeanFactory还是ApplicationContext

本节解释了BeanFactoryApplicationContext容器级别之间的差异,以及对启动(bootstrapping)过程的影响。

除非你有充分的理由不这样做,否则你应该使用ApplicationContextGenericApplicationContext及其子类AnnotationConfigApplicationContext是用于自定义启动(bootstrapping)的常见实现。这些是进入Spring核心容器的主要入口点,可用于所有常见场景:加载配置文件、触发类路径扫描(classpath scan)、以编程方式注册bean定义和带注解的类,以及(从Spring 5.0开始)注册函数型bean定义(functional bean definitions)。

由于ApplicationContext包含了BeanFactory的所有功能,因此通常建议使用ApplicationContext而不是普通的BeanFactory,除非在需要完全控制bean处理流程的场景下。在ApplicationContext(例如GenericApplicationContext实现)中,可以通过约定来检测几种类型的bean(即通过bean名称或bean类型来识别,特别是后处理器),而普通的DefaultListableBeanFactory则对任何特殊的bean都不了解(即不具备这种识别能力)。

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

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

表1. 特征矩阵

特性BeanFactoryApplicationContext
Bean实例化/连接
集成生命周期管理
自动注册BeanPostProcessor
自动注册BeanFactoryPostProcessor
便捷的MessageSource访问(用于国际化)
内置的ApplicationEvent发布机制

要显式地向DefaultListableBeanFactory注册一个bean后处理器,您需要通过编程方式调用addBeanPostProcessor,如下例所示:

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

要将BeanFactoryPostProcessor应用于普通的DefaultListableBeanFactory,你需要调用其postProcessBeanFactory方法,如下例所示:

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);

在这两种情况下,显式的注册步骤都显得很不方便,这就是为什么在基于Spring的应用中,人们更倾向于使用各种ApplicationContext的变体,而不是普通的DefaultListableBeanFactory。尤其是在典型的企业环境中,当需要依赖BeanFactoryPostProcessorBeanPostProcessor实例来扩展容器的功能时,这种偏好更为明显。

备注

AnnotationConfigApplicationContext 已注册了所有常见的注解后处理器,并且可以通过配置注解(如 @EnableTransactionManagement)在内部引入额外的后处理器。在 Spring 基于注解的配置模型的抽象层面上,bean 后处理器的概念就仅仅变成了容器内部的细节而已。