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
This commit is contained in:
@@ -148,14 +148,17 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||
// Process existing bean definition.
|
||||
if (existingBeanDefinition != null) {
|
||||
validateBeanDefinition(beanFactory, beanName);
|
||||
copyBeanDefinitionProperties(existingBeanDefinition, pseudoBeanDefinition);
|
||||
// Since validation may have registered a singleton as a side effect -- for example,
|
||||
// for a FactoryBean -- we need to remove the bean definition (which removes the
|
||||
// singleton as a side effect) and re-register the bean definition.
|
||||
registry.removeBeanDefinition(beanName);
|
||||
registry.registerBeanDefinition(beanName, existingBeanDefinition);
|
||||
}
|
||||
else {
|
||||
// There was no existing bean definition, so we register the pseudo bean definition
|
||||
// to ensure that a bean definition exists for the given bean name.
|
||||
registry.registerBeanDefinition(beanName, pseudoBeanDefinition);
|
||||
}
|
||||
|
||||
// At this point, we either removed an existing bean definition above, or
|
||||
// there was no bean definition to begin with. So, we register the pseudo bean
|
||||
// definition to ensure that a bean definition exists for the given bean name.
|
||||
registry.registerBeanDefinition(beanName, pseudoBeanDefinition);
|
||||
|
||||
Object override = overrideMetadata.createOverride(beanName, existingBeanDefinition, null);
|
||||
overrideMetadata.track(override, beanFactory);
|
||||
@@ -294,16 +297,6 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||
() -> "Unable to override bean '" + beanName + "': only singleton beans can be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the following properties of the source {@link BeanDefinition} to the
|
||||
* target: the {@linkplain BeanDefinition#isPrimary() primary flag} and the
|
||||
* {@linkplain BeanDefinition#isFallback() fallback flag}.
|
||||
*/
|
||||
private static void copyBeanDefinitionProperties(BeanDefinition source, RootBeanDefinition target) {
|
||||
target.setPrimary(source.isPrimary());
|
||||
target.setFallback(source.isFallback());
|
||||
}
|
||||
|
||||
|
||||
static class WrapEarlyBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
|
||||
PriorityOrdered {
|
||||
|
||||
@@ -315,7 +315,6 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||
|
||||
assertThatNoException().isThrownBy(context::refresh);
|
||||
assertThat(context.getBeanDefinition("descriptionBean"))
|
||||
.isNotSameAs(definition)
|
||||
.matches(BeanDefinition::isPrimary, "isPrimary")
|
||||
.matches(BeanDefinition::isFallback, "isFallback")
|
||||
.satisfies(d -> assertThat(d.getScope()).isEqualTo(""))
|
||||
@@ -324,9 +323,8 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void qualifiedElementIsSetToBeanOverrideField() {
|
||||
void qualifiedElementIsSetToBeanOverrideFieldForNonexistentBeanDefinition() {
|
||||
AnnotationConfigApplicationContext context = createContext(CaseByNameWithQualifier.class);
|
||||
context.registerBeanDefinition("descriptionBean", new RootBeanDefinition(String.class, () -> "ORIGINAL"));
|
||||
|
||||
assertThatNoException().isThrownBy(context::refresh);
|
||||
assertThat(context.getBeanDefinition("descriptionBean"))
|
||||
@@ -398,9 +396,12 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||
static class CaseByNameWithQualifier {
|
||||
|
||||
@Qualifier("preferThis")
|
||||
@DummyBean(beanName = "descriptionBean")
|
||||
@TestBean(name = "descriptionBean", enforceOverride = false)
|
||||
private String description;
|
||||
|
||||
static String descriptionBean() {
|
||||
return "overridden";
|
||||
}
|
||||
}
|
||||
|
||||
static class TestFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
Reference in New Issue
Block a user