测试中的 Bean 覆盖

测试中的 Bean 覆盖指的是通过在测试类上或测试类中的一个或多个非静态字段上添加注解,来覆盖测试类的 ApplicationContext 中特定 bean 的能力。

此功能旨在作为一种风险较低的替代方案,以取代通过 @Bean 并将 DefaultListableBeanFactorysetAllowBeanDefinitionOverriding 标志设置为 true 来注册 bean 的做法。

Spring TestContext 框架提供了两组用于 bean 覆盖的注解。

前者纯粹依赖 Spring,而后者依赖于 Mockito 第三方库。

自定义 Bean 覆盖支持

上述三个注解都基于 @BeanOverride 元注解及相关基础设施,允许定义自定义 bean 覆盖变体。

要实现自定义 bean 覆盖支持,需要以下内容:

  • 一个带有 @BeanOverride 元注解的注解,用于定义要使用的 BeanOverrideProcessor

  • 一个自定义的 BeanOverrideProcessor 实现

  • 一个或多个由处理器创建的具体 BeanOverrideHandler 实现

Spring TestContext 框架包含了以下 API 的实现,这些 API 支持 bean 覆盖并负责设置其余基础设施。

  • 一个 BeanFactoryPostProcessor

  • 一个 ContextCustomizerFactory

  • 一个 TestExecutionListener

spring-test 模块在其 META-INF/spring.factories 属性文件中注册了后两者的实现(BeanOverrideContextCustomizerFactoryBeanOverrideTestExecutionListener)。

bean 覆盖基础设施会搜索测试类上的注解以及测试类中带有 @BeanOverride 元注解的非静态字段上的注解,并实例化相应的 BeanOverrideProcessor,该处理器负责创建适当的 BeanOverrideHandler

内部的 BeanOverrideBeanFactoryPostProcessor 随后使用 bean 覆盖处理器,通过创建、替换或包装 bean(如相应 BeanOverrideStrategy 定义)来修改测试的 ApplicationContext

REPLACE

替换 bean。如果相应的 bean 不存在,则抛出异常。

REPLACE_OR_CREATE

如果 bean 存在,则替换它。如果相应的 bean 不存在,则创建一个新 bean。

WRAP

检索原始 bean 并将其包装。

当替换一个非单例 bean 时,该非单例 bean 将被替换为与适用 BeanOverrideHandler 创建的 bean 覆盖实例相对应的单例 bean,并且相应的 bean 定义将被转换为 singleton。因此,如果处理器覆盖了一个 prototype 或作用域 bean,则被覆盖的 bean 将被视为一个 singleton

当替换由 FactoryBean 创建的 bean 时,FactoryBean 本身将被替换为与适用 BeanOverrideHandler 创建的 bean 覆盖实例相对应的单例 bean。

当包装由 FactoryBean 创建的 bean 时,被包装的是由 FactoryBean 创建的对象,而不是 FactoryBean 本身。

与 Spring 的自动装配机制(例如,@Autowired 字段的解析)相反,TestContext 框架中的 bean 覆盖基础设施在定位 bean 时所能执行的启发式搜索是有限的。BeanOverrideProcessor 可以计算要覆盖的 bean 的名称,或者在给定带注解字段的类型及其限定注解的情况下,可以明确选择该 bean。

通常,BeanOverrideFactoryPostProcessor 会“按类型”选择 bean。或者,用户可以直接在自定义注解中提供 bean 名称。

BeanOverrideProcessor 实现也可以根据约定或其他方法在内部计算 bean 名称。

© . This site is unofficial and not affiliated with VMware.