Honor @Autowired(required=false) at parameter level

Includes a revision of the AutowireCandidateResolver SPI with default methods.

Issue: SPR-15268
This commit is contained in:
Juergen Hoeller
2017-05-03 13:42:16 +02:00
parent 07ef7a97c7
commit d74542ed21
7 changed files with 136 additions and 42 deletions

View File

@@ -699,8 +699,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(
ConstructorsCollectionResourceInjectionBean.class));
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorsCollectionResourceInjectionBean.class));
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
@@ -717,6 +716,46 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.destroySingletons();
}
@Test
public void testSingleConstructorInjectionWithMultipleCandidatesAsOrderedCollection() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SingleConstructorCollectionInjectionBean.class));
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
FixedOrder2NestedTestBean ntb1 = new FixedOrder2NestedTestBean();
bf.registerSingleton("nestedTestBean1", ntb1);
FixedOrder1NestedTestBean ntb2 = new FixedOrder1NestedTestBean();
bf.registerSingleton("nestedTestBean2", ntb2);
SingleConstructorCollectionInjectionBean bean = (SingleConstructorCollectionInjectionBean) bf.getBean("annotatedBean");
assertSame(tb, bean.getTestBean());
assertEquals(2, bean.getNestedTestBeans().size());
assertSame(ntb2, bean.getNestedTestBeans().get(0));
assertSame(ntb1, bean.getNestedTestBeans().get(1));
bf.destroySingletons();
}
@Test
public void testSingleConstructorInjectionWithEmptyCollection() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SingleConstructorCollectionInjectionBean.class));
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
SingleConstructorCollectionInjectionBean bean = (SingleConstructorCollectionInjectionBean) bf.getBean("annotatedBean");
assertSame(tb, bean.getTestBean());
assertNull(bean.getNestedTestBeans());
bf.destroySingletons();
}
@Test
public void testConstructorResourceInjectionWithMultipleCandidatesAndFallback() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -2757,6 +2796,28 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
public static class SingleConstructorCollectionInjectionBean {
private ITestBean testBean;
private List<NestedTestBean> nestedTestBeans;
public SingleConstructorCollectionInjectionBean(ITestBean testBean,
@Autowired(required = false) List<NestedTestBean> nestedTestBeans) {
this.testBean = testBean;
this.nestedTestBeans = nestedTestBeans;
}
public ITestBean getTestBean() {
return this.testBean;
}
public List<NestedTestBean> getNestedTestBeans() {
return this.nestedTestBeans;
}
}
@SuppressWarnings("serial")
public static class MyTestBeanMap extends LinkedHashMap<String, TestBean> {
}