diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 1cf6b17ff5..4d4ef662c5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -1317,7 +1317,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto DependencyDescriptor descriptor, Class requiredType) { if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { - candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this)); + Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); + candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { candidates.put(candidateName, getType(candidateName)); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index 635883fa92..da27d15171 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -681,6 +681,29 @@ public class AutowiredAnnotationBeanPostProcessorTests { } } + @Test + public void testConstructorResourceInjectionWithCollectionAndNullFromFactoryBean() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition( + ConstructorsCollectionResourceInjectionBean.class)); + TestBean tb = new TestBean(); + bf.registerSingleton("testBean", tb); + bf.registerBeanDefinition("nestedTestBean1", new RootBeanDefinition(NullNestedTestBeanFactoryBean.class)); + NestedTestBean ntb2 = new NestedTestBean(); + bf.registerSingleton("nestedTestBean2", ntb2); + + ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean"); + assertNull(bean.getTestBean3()); + assertSame(tb, bean.getTestBean4()); + assertEquals(2, bean.getNestedTestBeans().size()); + assertNull(bean.getNestedTestBeans().get(0)); + assertSame(ntb2, bean.getNestedTestBeans().get(1)); + bf.destroySingletons(); + } + @Test public void testConstructorResourceInjectionWithMultipleCandidatesAsCollection() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); @@ -860,23 +883,20 @@ public class AutowiredAnnotationBeanPostProcessorTests { bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("annotatedBean", bd); TestBean tb1 = new TestBean("tb1"); - TestBean tb2 = new TestBean("tb2"); bf.registerSingleton("testBean1", tb1); - bf.registerSingleton("testBean2", tb2); + RootBeanDefinition tb2 = new RootBeanDefinition(NullFactoryMethods.class); + tb2.setFactoryMethodName("createTestBean"); + bf.registerBeanDefinition("testBean2", tb2); MapConstructorInjectionBean bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean"); assertEquals(2, bean.getTestBeanMap().size()); - assertTrue(bean.getTestBeanMap().keySet().contains("testBean1")); - assertTrue(bean.getTestBeanMap().keySet().contains("testBean2")); - assertTrue(bean.getTestBeanMap().values().contains(tb1)); - assertTrue(bean.getTestBeanMap().values().contains(tb2)); + assertSame(tb1, bean.getTestBeanMap().get("testBean1")); + assertNull(bean.getTestBeanMap().get("testBean2")); bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean"); assertEquals(2, bean.getTestBeanMap().size()); - assertTrue(bean.getTestBeanMap().keySet().contains("testBean1")); - assertTrue(bean.getTestBeanMap().keySet().contains("testBean2")); - assertTrue(bean.getTestBeanMap().values().contains(tb1)); - assertTrue(bean.getTestBeanMap().values().contains(tb2)); + assertSame(tb1, bean.getTestBeanMap().get("testBean1")); + assertNull(bean.getTestBeanMap().get("testBean2")); } @Test