Relax singleton enforcement for Bean Overrides in the TestContext framework
In gh-33602, we introduced strict singleton enforcement for bean overrides -- for example, for @MockitoBean, @TestBean, etc. However, the use of BeanFactory#isSingleton(beanName) can result in a BeanCreationException for certain beans, such as a Spring Data JPA FactoryBean for a JpaRepository. In light of that, this commit relaxes the singleton enforcement in BeanOverrideBeanFactoryPostProcessor by only checking the result of BeanDefinition#isSingleton() for existing bean definitions. This commit also updates the Javadoc and reference documentation to reflect the status quo. See gh-33602 Closes gh-33800
This commit is contained in:
@@ -237,16 +237,16 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||
assertThat(context.getBean(beanName)).isEqualTo("overridden");
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaceBeanByNameWithMatchingBeanDefinitionForClassBasedNonSingletonFactoryBeanFails() {
|
||||
@Test // gh-33800
|
||||
void replaceBeanByNameWithMatchingBeanDefinitionForClassBasedNonSingletonFactoryBean() {
|
||||
String beanName = "descriptionBean";
|
||||
AnnotationConfigApplicationContext context = createContext(CaseByName.class);
|
||||
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition(NonSingletonStringFactoryBean.class);
|
||||
context.registerBeanDefinition(beanName, factoryBeanDefinition);
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(context::refresh)
|
||||
.withMessage("Unable to override bean 'descriptionBean': only singleton beans can be overridden.");
|
||||
assertThatNoException().isThrownBy(context::refresh);
|
||||
assertThat(context.isSingleton(beanName)).as("isSingleton").isTrue();
|
||||
assertThat(context.getBean(beanName)).isEqualTo("overridden");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -261,16 +261,16 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||
assertThat(context.getBean(beanName, MessageService.class).getMessage()).isEqualTo("overridden");
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaceBeanByNameWithMatchingBeanDefinitionForInterfaceBasedNonSingletonFactoryBeanFails() {
|
||||
@Test // gh-33800
|
||||
void replaceBeanByNameWithMatchingBeanDefinitionForInterfaceBasedNonSingletonFactoryBean() {
|
||||
String beanName = "messageServiceBean";
|
||||
AnnotationConfigApplicationContext context = createContext(MessageServiceTestCase.class);
|
||||
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition(NonSingletonMessageServiceFactoryBean.class);
|
||||
context.registerBeanDefinition(beanName, factoryBeanDefinition);
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(context::refresh)
|
||||
.withMessage("Unable to override bean 'messageServiceBean': only singleton beans can be overridden.");
|
||||
assertThatNoException().isThrownBy(context::refresh);
|
||||
assertThat(context.isSingleton(beanName)).as("isSingleton").isTrue();
|
||||
assertThat(context.getBean(beanName, MessageService.class).getMessage()).isEqualTo("overridden");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user