跳到主要内容
版本:7.0.3

测试中的Bean覆盖

Hunyuan 7b 中英对照 Bean Overriding in Tests

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

备注

此功能旨在作为一种风险较低的替代方案,用于通过@Bean注册bean,同时将DefaultListableBeanFactorysetAllowBeanDefinitionOverriding标志设置为true

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

前者完全依赖于Spring,而后者则依赖于[Mockito](https://site Mockito.org/)这个第三方库。

自定义Bean覆盖支持

上述三种注解都是基于@BeanOverride元注释及其相关基础设施构建的,这种元注释允许用户定义自定义的bean覆盖变体。

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

  • 一个带有@BeanOverride元注释的注解,用于定义要使用的BeanOverrideProcessor
  • 一个自定义的BeanOverrideProcessor实现
  • 由该处理器创建的一个或多个具体的BeanOverrideHandler实现

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

  • 一个 BeanFactoryPostProcessor
  • 一个 ContextCustomizerFactory
  • 一个 TestExecutionListener

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

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

内部的BeanOverrideBeanFactoryPostProcessor随后会使用bean覆盖处理器来修改测试的ApplicationContext,通过创建、替换或包装bean来实现这一目标,具体操作方式由相应的BeanOverrideStrategy定义:

REPLACE

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

REPLACE_OR_CREATE

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

WRAP

检索原始bean并将其包装起来。

提示

在替换非单例bean时,该非单例bean将被替换为由相应的BeanOverrideHandler创建的单例bean实例,且对应的bean定义也将被转换为singleton类型。因此,如果某个处理器覆盖了prototypescoped类型的bean,那么被覆盖的bean将被视为singleton

当替换由FactoryBean创建的bean时,FactoryBean本身将被替换为由相应的BeanOverrideHandler创建的单例bean实例。

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

备注

与Spring的自动装配机制(例如,@Autowired字段的解析)不同,TestContext框架中的Bean覆盖基础设施在定位bean时可使用的启发式方法较为有限。BeanOverrideProcessor要么可以计算出需要覆盖的bean的名称,要么可以根据被注解字段的类型及其附加注解来明确地选择该bean。

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

BeanOverrideProcessor的实现也可能基于某种约定或其他方法在内部计算bean的名称。