BeanFactory API

BeanFactory API 为 Spring 的 IoC 功能提供了底层基础。其特定契约主要用于与 Spring 的其他部分和相关的第三方框架集成,并且其 DefaultListableBeanFactory 实现是高级 GenericApplicationContext 容器中的一个关键委托。

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

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

BeanFactory 还是 ApplicationContext

本节解释了 BeanFactoryApplicationContext 容器级别之间的差异以及对引导的影响。

除非你有充分的理由不这样做,否则你应该使用 ApplicationContext,其中 GenericApplicationContext 及其子类 AnnotationConfigApplicationContext 是自定义引导的常见实现。对于所有常见目的,这些是 Spring 核心容器的主要入口点:加载配置文件、触发类路径扫描、以编程方式注册 Bean 定义和带注释的类,以及(从 5.0 开始)注册函数 Bean 定义。

由于 ApplicationContext 包括 BeanFactory 的所有功能,因此通常推荐使用它,而不是普通的 BeanFactory,但需要完全控制 Bean 处理的情况除外。在 ApplicationContext(例如 GenericApplicationContext 实现)中,会根据约定(即按 Bean 名称或 Bean 类型,特别是后置处理器)检测到几种 Bean,而普通的 DefaultListableBeanFactory 则不区分任何特殊 Bean。

对于许多扩展的容器功能,例如注释处理和 AOP 代理,BeanPostProcessor 扩展点 至关重要。如果你只使用普通的 DefaultListableBeanFactory,则默认情况下不会检测并激活此类后置处理器。这种情况可能会令人困惑,因为你的 Bean 配置实际上没有任何问题。相反,在这种情况下,需要通过其他设置完全引导容器。

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

表 1. 功能矩阵
功能 BeanFactory ApplicationContext

Bean 实例化/连接

集成生命周期管理

自动 BeanPostProcessor 注册

自动 BeanFactoryPostProcessor 注册

便捷的 MessageSource 访问(用于国际化)

内置的ApplicationEvent发布机制

要使用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更受欢迎,尤其是在依赖BeanFactoryPostProcessorBeanPostProcessor实例以在典型的企业设置中扩展容器功能时。

AnnotationConfigApplicationContext已注册所有常见的注释后置处理器,并且可能通过配置注释(例如@EnableTransactionManagement)在后台引入其他处理器。在基于 Spring 的注释配置模型的抽象级别上,Bean 后置处理器的概念仅仅是内部容器的详细信息。