Accept non-generic type match as a fallback
DefaultListableBeanFactory performs a fallback check for autowire candidates now, which GenericTypeAwareAutowireCandidateResolver implements to accept raw type matches if the target class has unresolvable type variables. Full generic matches are still preferred; the BeanFactory will only start looking for fallback matches if the first pass led to an empty result. Issue: SPR-10993 Issue: SPR-11004
This commit is contained in:
@@ -1305,6 +1305,130 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertSame(ir, bean.integerRepositoryMap.get("integerRepo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericsBasedConstructorInjectionWithNonTypedTarget() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
GenericRepository gr = new GenericRepository();
|
||||
bf.registerSingleton("genericRepo", gr);
|
||||
|
||||
RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(gr, bean.stringRepository);
|
||||
assertSame(gr, bean.integerRepository);
|
||||
assertSame(1, bean.stringRepositoryArray.length);
|
||||
assertSame(1, bean.integerRepositoryArray.length);
|
||||
assertSame(gr, bean.stringRepositoryArray[0]);
|
||||
assertSame(gr, bean.integerRepositoryArray[0]);
|
||||
assertSame(1, bean.stringRepositoryList.size());
|
||||
assertSame(1, bean.integerRepositoryList.size());
|
||||
assertSame(gr, bean.stringRepositoryList.get(0));
|
||||
assertSame(gr, bean.integerRepositoryList.get(0));
|
||||
assertSame(1, bean.stringRepositoryMap.size());
|
||||
assertSame(1, bean.integerRepositoryMap.size());
|
||||
assertSame(gr, bean.stringRepositoryMap.get("genericRepo"));
|
||||
assertSame(gr, bean.integerRepositoryMap.get("genericRepo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericsBasedConstructorInjectionWithNonGenericTarget() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
SimpleRepository ngr = new SimpleRepository();
|
||||
bf.registerSingleton("simpleRepo", ngr);
|
||||
|
||||
RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(ngr, bean.stringRepository);
|
||||
assertSame(ngr, bean.integerRepository);
|
||||
assertSame(1, bean.stringRepositoryArray.length);
|
||||
assertSame(1, bean.integerRepositoryArray.length);
|
||||
assertSame(ngr, bean.stringRepositoryArray[0]);
|
||||
assertSame(ngr, bean.integerRepositoryArray[0]);
|
||||
assertSame(1, bean.stringRepositoryList.size());
|
||||
assertSame(1, bean.integerRepositoryList.size());
|
||||
assertSame(ngr, bean.stringRepositoryList.get(0));
|
||||
assertSame(ngr, bean.integerRepositoryList.get(0));
|
||||
assertSame(1, bean.stringRepositoryMap.size());
|
||||
assertSame(1, bean.integerRepositoryMap.size());
|
||||
assertSame(ngr, bean.stringRepositoryMap.get("simpleRepo"));
|
||||
assertSame(ngr, bean.integerRepositoryMap.get("simpleRepo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericsBasedConstructorInjectionWithMixedTargets() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
StringRepository sr = new StringRepository();
|
||||
bf.registerSingleton("stringRepo", sr);
|
||||
GenericRepository gr = new GenericRepositorySubclass();
|
||||
bf.registerSingleton("genericRepo", gr);
|
||||
|
||||
RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(sr, bean.stringRepository);
|
||||
assertSame(gr, bean.integerRepository);
|
||||
assertSame(1, bean.stringRepositoryArray.length);
|
||||
assertSame(1, bean.integerRepositoryArray.length);
|
||||
assertSame(sr, bean.stringRepositoryArray[0]);
|
||||
assertSame(gr, bean.integerRepositoryArray[0]);
|
||||
assertSame(1, bean.stringRepositoryList.size());
|
||||
assertSame(1, bean.integerRepositoryList.size());
|
||||
assertSame(sr, bean.stringRepositoryList.get(0));
|
||||
assertSame(gr, bean.integerRepositoryList.get(0));
|
||||
assertSame(1, bean.stringRepositoryMap.size());
|
||||
assertSame(1, bean.integerRepositoryMap.size());
|
||||
assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
|
||||
assertSame(gr, bean.integerRepositoryMap.get("genericRepo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericsBasedConstructorInjectionWithMixedTargetsIncludingNonGeneric() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
StringRepository sr = new StringRepository();
|
||||
bf.registerSingleton("stringRepo", sr);
|
||||
SimpleRepository ngr = new SimpleRepositorySubclass();
|
||||
bf.registerSingleton("simpleRepo", ngr);
|
||||
|
||||
RepositoryConstructorInjectionBean bean = (RepositoryConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertSame(sr, bean.stringRepository);
|
||||
assertSame(ngr, bean.integerRepository);
|
||||
assertSame(1, bean.stringRepositoryArray.length);
|
||||
assertSame(1, bean.integerRepositoryArray.length);
|
||||
assertSame(sr, bean.stringRepositoryArray[0]);
|
||||
assertSame(ngr, bean.integerRepositoryArray[0]);
|
||||
assertSame(1, bean.stringRepositoryList.size());
|
||||
assertSame(1, bean.integerRepositoryList.size());
|
||||
assertSame(sr, bean.stringRepositoryList.get(0));
|
||||
assertSame(ngr, bean.integerRepositoryList.get(0));
|
||||
assertSame(1, bean.stringRepositoryMap.size());
|
||||
assertSame(1, bean.integerRepositoryMap.size());
|
||||
assertSame(sr, bean.stringRepositoryMap.get("stringRepo"));
|
||||
assertSame(ngr, bean.integerRepositoryMap.get("simpleRepo"));
|
||||
}
|
||||
|
||||
|
||||
public static class ResourceInjectionBean {
|
||||
|
||||
@@ -1859,6 +1983,18 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
public static class IntegerRepository implements Repository<Integer> {
|
||||
}
|
||||
|
||||
public static class GenericRepository<T> implements Repository<T> {
|
||||
}
|
||||
|
||||
public static class GenericRepositorySubclass extends GenericRepository {
|
||||
}
|
||||
|
||||
public static class SimpleRepository implements Repository {
|
||||
}
|
||||
|
||||
public static class SimpleRepositorySubclass extends SimpleRepository {
|
||||
}
|
||||
|
||||
|
||||
public static class RepositoryFieldInjectionBean {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user