Complete treatment of RuntimeBeanReference in BeanDefinitionValueResolver

See gh-35101
This commit is contained in:
Juergen Hoeller 2025-06-26 17:15:31 +02:00
parent f7fef93842
commit 4b44a34692
3 changed files with 34 additions and 16 deletions

View File

@ -107,6 +107,7 @@ public class RuntimeBeanReference implements BeanReference {
* @since 7.0 * @since 7.0
*/ */
public RuntimeBeanReference(String beanName, Class<?> beanType, boolean toParent) { public RuntimeBeanReference(String beanName, Class<?> beanType, boolean toParent) {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanType, "'beanType' must not be null"); Assert.notNull(beanType, "'beanType' must not be null");
this.beanName = beanName; this.beanName = beanName;
this.beanType = beanType; this.beanType = beanType;

View File

@ -333,6 +333,7 @@ public class BeanDefinitionValueResolver {
try { try {
Object bean; Object bean;
Class<?> beanType = ref.getBeanType(); Class<?> beanType = ref.getBeanType();
String resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
if (ref.isToParent()) { if (ref.isToParent()) {
BeanFactory parent = this.beanFactory.getParentBeanFactory(); BeanFactory parent = this.beanFactory.getParentBeanFactory();
if (parent == null) { if (parent == null) {
@ -342,21 +343,25 @@ public class BeanDefinitionValueResolver {
" in parent factory: no parent factory available"); " in parent factory: no parent factory available");
} }
if (beanType != null) { if (beanType != null) {
bean = parent.getBean(beanType); bean = (parent.containsBean(resolvedName) ?
parent.getBean(resolvedName, beanType) : parent.getBean(beanType));
} }
else { else {
bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName()))); bean = parent.getBean(resolvedName);
} }
} }
else { else {
String resolvedName;
if (beanType != null) { if (beanType != null) {
if (this.beanFactory.containsBean(resolvedName)) {
bean = this.beanFactory.getBean(resolvedName, beanType);
}
else {
NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType); NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
bean = namedBean.getBeanInstance(); bean = namedBean.getBeanInstance();
resolvedName = namedBean.getBeanName(); resolvedName = namedBean.getBeanName();
} }
}
else { else {
resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
bean = this.beanFactory.getBean(resolvedName); bean = this.beanFactory.getBean(resolvedName);
} }
this.beanFactory.registerDependentBean(resolvedName, this.beanName); this.beanFactory.registerDependentBean(resolvedName, this.beanName);

View File

@ -555,21 +555,33 @@ class BeanFactoryUtilsTests {
} }
@Test @Test
void supportsMultipleTypesWithProperty() { void supportsMultipleTypesWithPropertyAndSingleBean() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
SupportsTypeSmartFactoryBean sfb = new SupportsTypeSmartFactoryBean(); SupportsTypeSmartFactoryBean sfb = new SupportsTypeSmartFactoryBean();
lbf.registerSingleton("sfb", sfb); lbf.registerSingleton("sfb", sfb);
RootBeanDefinition rbd1 = new RootBeanDefinition(PropertyRecipient.class); RootBeanDefinition rbd = new RootBeanDefinition(PropertyRecipient.class);
rbd1.getPropertyValues().add("sfb", new RuntimeBeanReference(ITestBean.class)); rbd.getPropertyValues().add("sfb", new RuntimeBeanReference(ITestBean.class));
lbf.registerBeanDefinition("recipient1", rbd1); lbf.registerBeanDefinition("recipient", rbd);
RootBeanDefinition rbd2 = new RootBeanDefinition(PropertyRecipient.class); assertThat(lbf.getBean("recipient", PropertyRecipient.class).sfb)
rbd2.getPropertyValues().add("sfb", new RuntimeBeanReference("sfb", ITestBean.class)); .isSameAs(lbf.getBean("sfb", ITestBean.class));
lbf.registerBeanDefinition("recipient2", rbd2); }
assertThat(lbf.getBean("recipient1", PropertyRecipient.class).sfb).isSameAs(lbf.getBean("sfb", ITestBean.class)); @Test
assertThat(lbf.getBean("recipient2", PropertyRecipient.class).sfb).isSameAs(lbf.getBean("sfb", ITestBean.class)); void supportsMultipleTypesWithPropertyAndMultipleBeans() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
SupportsTypeSmartFactoryBean sfb = new SupportsTypeSmartFactoryBean();
lbf.registerSingleton("sfb", sfb);
SupportsTypeSmartFactoryBean other = new SupportsTypeSmartFactoryBean();
lbf.registerSingleton("other", other);
RootBeanDefinition rbd = new RootBeanDefinition(PropertyRecipient.class);
rbd.getPropertyValues().add("sfb", new RuntimeBeanReference("sfb", ITestBean.class));
lbf.registerBeanDefinition("recipient", rbd);
assertThat(lbf.getBean("recipient", PropertyRecipient.class).sfb)
.isSameAs(lbf.getBean("sfb", ITestBean.class));
} }