Consistently override (and prevent overriding for) aliases with bean definitions
Closes gh-27866
This commit is contained in:
parent
e5af4aa608
commit
6b1c2dc944
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -49,7 +49,7 @@ public class BeanDefinitionOverrideException extends BeanDefinitionStoreExceptio
|
||||||
|
|
||||||
super(beanDefinition.getResourceDescription(), beanName,
|
super(beanDefinition.getResourceDescription(), beanName,
|
||||||
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
|
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
|
||||||
"': There is already [" + existingDefinition + "] bound.");
|
"' since there is already [" + existingDefinition + "] bound.");
|
||||||
this.beanDefinition = beanDefinition;
|
this.beanDefinition = beanDefinition;
|
||||||
this.existingDefinition = existingDefinition;
|
this.existingDefinition = existingDefinition;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -994,6 +994,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
this.beanDefinitionMap.put(beanName, beanDefinition);
|
this.beanDefinitionMap.put(beanName, beanDefinition);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (isAlias(beanName)) {
|
||||||
|
if (!isAllowBeanDefinitionOverriding()) {
|
||||||
|
String aliasedName = canonicalName(beanName);
|
||||||
|
if (containsBeanDefinition(aliasedName)) { // alias for existing bean definition
|
||||||
|
throw new BeanDefinitionOverrideException(
|
||||||
|
beanName, beanDefinition, getBeanDefinition(aliasedName));
|
||||||
|
}
|
||||||
|
else { // alias pointing to non-existing bean definition
|
||||||
|
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
|
||||||
|
"Cannot register bean definition for bean '" + beanName +
|
||||||
|
"' since there is already an alias for bean '" + aliasedName + "' bound.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
removeAlias(beanName);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (hasBeanCreationStarted()) {
|
if (hasBeanCreationStarted()) {
|
||||||
// Cannot modify startup-time collection elements anymore (for stable iteration)
|
// Cannot modify startup-time collection elements anymore (for stable iteration)
|
||||||
synchronized (this.beanDefinitionMap) {
|
synchronized (this.beanDefinitionMap) {
|
||||||
|
|
|
||||||
|
|
@ -854,8 +854,11 @@ class DefaultListableBeanFactoryTests {
|
||||||
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
|
||||||
lbf.registerAlias("otherTest", "test2");
|
lbf.registerAlias("otherTest", "test2");
|
||||||
lbf.registerAlias("test", "test2");
|
lbf.registerAlias("test", "test2");
|
||||||
|
lbf.registerAlias("test", "testX");
|
||||||
|
lbf.registerBeanDefinition("testX", new RootBeanDefinition(TestBean.class));
|
||||||
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
|
||||||
assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class);
|
assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class);
|
||||||
|
assertThat(lbf.getBean("testX")).isInstanceOf(TestBean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -864,6 +867,7 @@ class DefaultListableBeanFactoryTests {
|
||||||
BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
|
BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
|
||||||
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
|
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
|
||||||
lbf.registerBeanDefinition("test", oldDef);
|
lbf.registerBeanDefinition("test", oldDef);
|
||||||
|
lbf.registerAlias("test", "testX");
|
||||||
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
|
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
|
||||||
lbf.registerBeanDefinition("test", newDef))
|
lbf.registerBeanDefinition("test", newDef))
|
||||||
.satisfies(ex -> {
|
.satisfies(ex -> {
|
||||||
|
|
@ -871,6 +875,13 @@ class DefaultListableBeanFactoryTests {
|
||||||
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
|
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
|
||||||
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
|
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
|
||||||
});
|
});
|
||||||
|
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
|
||||||
|
lbf.registerBeanDefinition("testX", newDef))
|
||||||
|
.satisfies(ex -> {
|
||||||
|
assertThat(ex.getBeanName()).isEqualTo("testX");
|
||||||
|
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
|
||||||
|
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue