此版本仍在开发中,尚未稳定。如需最新的稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

测试中的Bean覆盖

在测试中的Bean覆盖是指有能力为一个测试类覆盖 ApplicationContext 中的特定Bean,通过在测试类或测试类中的一个或多个 非静态字段上使用注解来实现这一功能。spring-doc.cadn.net.cn

此功能旨在作为通过@BeanDefaultListableBeanFactory setAllowBeanDefinitionOverriding标志设置为true注册bean做法的一种较低风险的替代方案。

Spring TestContext 框架为bean覆盖提供了两套注解。spring-doc.cadn.net.cn

前者完全依赖于Spring,而后者集则依赖于第三方库 Mockitospring-doc.cadn.net.cn

自定义Bean覆盖支持

上述提到的三个注解建立在@BeanOverride元注解及其关联基础设施之上,这允许用户定义自定义的bean覆盖变体。spring-doc.cadn.net.cn

要实现自定义bean覆盖支持,需要以下内容:spring-doc.cadn.net.cn

Spring TestContext 框架包含以下 API 的实现,这些实现支持 Bean 覆盖,并负责搭建其余的基础设施。spring-doc.cadn.net.cn

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

bean覆盖基础设施会在测试类上以及被@BeanOverride元注解标记的测试类中的非静态字段上搜索注解,并实例化相应的BeanOverrideProcessor,该BeanOverrideProcessor负责创建一个合适的BeanOverrideHandlerspring-doc.cadn.net.cn

内部的BeanOverrideBeanFactoryPostProcessor接着使用bean覆盖处理器来根据相应的BeanOverrideStrategy定义,通过创建、替换或包装beans来改变测试的ApplicationContext:spring-doc.cadn.net.cn

REPLACE

替换指定的bean。如果不存在相应的bean,则抛出异常。spring-doc.cadn.net.cn

REPLACE_OR_CREATE

如果存在,则替换该bean。如果不存在相应的bean,则创建一个新的bean。spring-doc.cadn.net.cn

WRAP

获取原始bean并对其进行包装。spring-doc.cadn.net.cn

在替换非单例bean时,非单例bean将被替换为由相应BeanOverrideHandler创建的bean覆盖实例对应的单例bean,并且相应的bean定义将转换为singleton。因此,如果处理器覆盖了prototype或作用域bean,被覆盖的bean将被视为singletonspring-doc.cadn.net.cn

当使用FactoryBean创建的bean被替换时,FactoryBean本身将被替换为与通过适用的BeanOverrideHandler创建的bean覆盖实例相对应的单例bean。spring-doc.cadn.net.cn

当使用FactoryBean创建的bean进行包装时,将被包装的是由FactoryBean创建的对象,而不是FactoryBean本身。spring-doc.cadn.net.cn

与Spring的自动装配机制(例如,解析@Autowired字段)不同,TestContext框架中的bean覆盖基础设施具有有限的启发式方法来定位bean。要么BeanOverrideProcessor可以计算出要覆盖的bean的名称,要么可以根据注解字段的类型及其限定注解无歧义地选择它。spring-doc.cadn.net.cn

通常,bean会通过BeanOverrideFactoryPostProcessor“按类型”被选择。或者,用户可以直接在自定义注解中提供bean名称。spring-doc.cadn.net.cn

BeanOverrideProcessor 实现也可能根据约定或其他方法内部计算bean名称。spring-doc.cadn.net.cn