Skip to content

Commit a21c557

Browse files
committed
Do not replace existing Bean Override definition with pseudo-definition
Prior to this commit, BeanOverrideBeanFactoryPostProcessor replaced existing bean definitions with "pseudo" bean definitions; however, that is unnecessary. An existing BeanDefinition is suitable as-is and does not need to be replaced with a pseudo/fake definition. To address that, this commit reregisters an existing bean definition and only registers a new bean definition when creating a bean definition for a nonexistent bean. As a side effect, we no longer need to copy primary and fallback flags. Closes gh-33627
1 parent 56a0a33 commit a21c557

File tree

2 files changed

+14
-20
lines changed

2 files changed

+14
-20
lines changed

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessor.java

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,17 @@ else if (enforceExistingDefinition) {
148148
// Process existing bean definition.
149149
if (existingBeanDefinition != null) {
150150
validateBeanDefinition(beanFactory, beanName);
151-
copyBeanDefinitionProperties(existingBeanDefinition, pseudoBeanDefinition);
151+
// Since validation may have registered a singleton as a side effect -- for example,
152+
// for a FactoryBean -- we need to remove the bean definition (which removes the
153+
// singleton as a side effect) and re-register the bean definition.
152154
registry.removeBeanDefinition(beanName);
155+
registry.registerBeanDefinition(beanName, existingBeanDefinition);
156+
}
157+
else {
158+
// There was no existing bean definition, so we register the pseudo bean definition
159+
// to ensure that a bean definition exists for the given bean name.
160+
registry.registerBeanDefinition(beanName, pseudoBeanDefinition);
153161
}
154-
155-
// At this point, we either removed an existing bean definition above, or
156-
// there was no bean definition to begin with. So, we register the pseudo bean
157-
// definition to ensure that a bean definition exists for the given bean name.
158-
registry.registerBeanDefinition(beanName, pseudoBeanDefinition);
159162

160163
Object override = overrideMetadata.createOverride(beanName, existingBeanDefinition, null);
161164
overrideMetadata.track(override, beanFactory);
@@ -294,16 +297,6 @@ private static void validateBeanDefinition(ConfigurableListableBeanFactory beanF
294297
() -> "Unable to override bean '" + beanName + "': only singleton beans can be overridden.");
295298
}
296299

297-
/**
298-
* Copy the following properties of the source {@link BeanDefinition} to the
299-
* target: the {@linkplain BeanDefinition#isPrimary() primary flag} and the
300-
* {@linkplain BeanDefinition#isFallback() fallback flag}.
301-
*/
302-
private static void copyBeanDefinitionProperties(BeanDefinition source, RootBeanDefinition target) {
303-
target.setPrimary(source.isPrimary());
304-
target.setFallback(source.isFallback());
305-
}
306-
307300

308301
static class WrapEarlyBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
309302
PriorityOrdered {

spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ void replaceBeanByNameWithMatchingBeanDefinitionRetainsPrimaryAndFallbackFlags()
315315

316316
assertThatNoException().isThrownBy(context::refresh);
317317
assertThat(context.getBeanDefinition("descriptionBean"))
318-
.isNotSameAs(definition)
319318
.matches(BeanDefinition::isPrimary, "isPrimary")
320319
.matches(BeanDefinition::isFallback, "isFallback")
321320
.satisfies(d -> assertThat(d.getScope()).isEqualTo(""))
@@ -324,9 +323,8 @@ void replaceBeanByNameWithMatchingBeanDefinitionRetainsPrimaryAndFallbackFlags()
324323
}
325324

326325
@Test
327-
void qualifiedElementIsSetToBeanOverrideField() {
326+
void qualifiedElementIsSetToBeanOverrideFieldForNonexistentBeanDefinition() {
328327
AnnotationConfigApplicationContext context = createContext(CaseByNameWithQualifier.class);
329-
context.registerBeanDefinition("descriptionBean", new RootBeanDefinition(String.class, () -> "ORIGINAL"));
330328

331329
assertThatNoException().isThrownBy(context::refresh);
332330
assertThat(context.getBeanDefinition("descriptionBean"))
@@ -398,9 +396,12 @@ static class CaseOverrideBeanProducedByFactoryBean {
398396
static class CaseByNameWithQualifier {
399397

400398
@Qualifier("preferThis")
401-
@DummyBean(beanName = "descriptionBean")
399+
@TestBean(name = "descriptionBean", enforceOverride = false)
402400
private String description;
403401

402+
static String descriptionBean() {
403+
return "overridden";
404+
}
404405
}
405406

406407
static class TestFactoryBean implements FactoryBean<Object> {

0 commit comments

Comments
 (0)