Consistent type-based bean lookup for RuntimeBeanReference
See gh-35101
This commit is contained in:
		
							parent
							
								
									06ef82e9a5
								
							
						
					
					
						commit
						c5da405314
					
				| 
						 | 
				
			
			@ -87,6 +87,32 @@ public class RuntimeBeanReference implements BeanReference {
 | 
			
		|||
		this.toParent = toParent;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new RuntimeBeanReference to a bean of the given type.
 | 
			
		||||
	 * @param beanName name of the target bean
 | 
			
		||||
	 * @param beanType type of the target bean
 | 
			
		||||
	 * @since 7.0
 | 
			
		||||
	 */
 | 
			
		||||
	public RuntimeBeanReference(String beanName, Class<?> beanType) {
 | 
			
		||||
		this(beanName, beanType, false);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new RuntimeBeanReference to a bean of the given type,
 | 
			
		||||
	 * with the option to mark it as reference to a bean in the parent factory.
 | 
			
		||||
	 * @param beanName name of the target bean
 | 
			
		||||
	 * @param beanType type of the target bean
 | 
			
		||||
	 * @param toParent whether this is an explicit reference to a bean in the
 | 
			
		||||
	 * parent factory
 | 
			
		||||
	 * @since 7.0
 | 
			
		||||
	 */
 | 
			
		||||
	public RuntimeBeanReference(String beanName, Class<?> beanType, boolean toParent) {
 | 
			
		||||
		Assert.notNull(beanType, "'beanType' must not be null");
 | 
			
		||||
		this.beanName = beanName;
 | 
			
		||||
		this.beanType = beanType;
 | 
			
		||||
		this.toParent = toParent;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the requested bean name, or the fully-qualified type name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1588,7 +1588,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
 | 
			
		|||
	private <T> @Nullable NamedBeanHolder<T> resolveNamedBean(
 | 
			
		||||
			String beanName, ResolvableType requiredType, @Nullable Object @Nullable [] args) throws BeansException {
 | 
			
		||||
 | 
			
		||||
		Object bean = getBean(beanName, null, args);
 | 
			
		||||
		Object bean = (args != null ? getBean(beanName, args) : resolveBean(beanName, requiredType));
 | 
			
		||||
		if (bean instanceof NullBean) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ import org.jspecify.annotations.Nullable;
 | 
			
		|||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
 | 
			
		||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 | 
			
		||||
import org.springframework.beans.factory.support.RootBeanDefinition;
 | 
			
		||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
 | 
			
		||||
| 
						 | 
				
			
			@ -465,9 +466,9 @@ class BeanFactoryUtilsTests {
 | 
			
		|||
		lbf.registerSingleton("sfb1", sfb1);
 | 
			
		||||
		lbf.registerSingleton("sfb2", sfb2);
 | 
			
		||||
		lbf.registerBeanDefinition("recipient",
 | 
			
		||||
				new RootBeanDefinition(Recipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false));
 | 
			
		||||
				new RootBeanDefinition(ConstructorRecipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false));
 | 
			
		||||
 | 
			
		||||
		Recipient recipient = lbf.getBean("recipient", Recipient.class);
 | 
			
		||||
		ConstructorRecipient recipient = lbf.getBean("recipient", ConstructorRecipient.class);
 | 
			
		||||
		assertThat(recipient.sfb1).isSameAs(lbf.getBean("sfb1", TestBean.class));
 | 
			
		||||
		assertThat(recipient.sfb2).isSameAs(lbf.getBean("sfb2", TestBean.class));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -553,6 +554,24 @@ class BeanFactoryUtilsTests {
 | 
			
		|||
		assertThat(lbf.getBean("sfb2")).isInstanceOf(String.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void supportsMultipleTypesWithProperty() {
 | 
			
		||||
		DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
 | 
			
		||||
		SupportsTypeSmartFactoryBean sfb = new SupportsTypeSmartFactoryBean();
 | 
			
		||||
		lbf.registerSingleton("sfb", sfb);
 | 
			
		||||
 | 
			
		||||
		RootBeanDefinition rbd1 = new RootBeanDefinition(PropertyRecipient.class);
 | 
			
		||||
		rbd1.getPropertyValues().add("sfb", new RuntimeBeanReference(ITestBean.class));
 | 
			
		||||
		lbf.registerBeanDefinition("recipient1", rbd1);
 | 
			
		||||
 | 
			
		||||
		RootBeanDefinition rbd2 = new RootBeanDefinition(PropertyRecipient.class);
 | 
			
		||||
		rbd2.getPropertyValues().add("sfb", new RuntimeBeanReference("sfb", ITestBean.class));
 | 
			
		||||
		lbf.registerBeanDefinition("recipient2", rbd2);
 | 
			
		||||
 | 
			
		||||
		assertThat(lbf.getBean("recipient1", PropertyRecipient.class).sfb).isSameAs(lbf.getBean("sfb", ITestBean.class));
 | 
			
		||||
		assertThat(lbf.getBean("recipient2", PropertyRecipient.class).sfb).isSameAs(lbf.getBean("sfb", ITestBean.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
	@interface ControllerAdvice {
 | 
			
		||||
| 
						 | 
				
			
			@ -650,9 +669,10 @@ class BeanFactoryUtilsTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	static class Recipient {
 | 
			
		||||
	static class ConstructorRecipient {
 | 
			
		||||
 | 
			
		||||
		public Recipient(ITestBean sfb1, ITestBean sfb2, List<ITestBean> testBeanList, List<CharSequence> stringList,
 | 
			
		||||
		public ConstructorRecipient(ITestBean sfb1, ITestBean sfb2,
 | 
			
		||||
				List<ITestBean> testBeanList, List<CharSequence> stringList,
 | 
			
		||||
				ObjectProvider<ITestBean> testBeanProvider, ObjectProvider<CharSequence> stringProvider) {
 | 
			
		||||
			this.sfb1 = sfb1;
 | 
			
		||||
			this.sfb2 = sfb2;
 | 
			
		||||
| 
						 | 
				
			
			@ -675,4 +695,14 @@ class BeanFactoryUtilsTests {
 | 
			
		|||
		ObjectProvider<CharSequence> stringProvider;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	static class PropertyRecipient {
 | 
			
		||||
 | 
			
		||||
		ITestBean sfb;
 | 
			
		||||
 | 
			
		||||
		public void setSfb(ITestBean sfb) {
 | 
			
		||||
			this.sfb = sfb;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue