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 3c2635990f7..4a6654044c7 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 @@ -1268,9 +1268,9 @@ public class AutowiredAnnotationBeanPostProcessorTests { rbd.getConstructorArgumentValues().addGenericArgumentValue(Repository.class); bf.registerBeanDefinition("integerRepo", rbd); + RepositoryFieldInjectionBeanWithQualifiers bean = (RepositoryFieldInjectionBeanWithQualifiers) bf.getBean("annotatedBean"); Repository sr = bf.getBean("stringRepo", Repository.class); Repository ir = bf.getBean("integerRepo", Repository.class); - RepositoryFieldInjectionBeanWithQualifiers bean = (RepositoryFieldInjectionBeanWithQualifiers) bf.getBean("annotatedBean"); assertSame(sr, bean.stringRepository); assertSame(ir, bean.integerRepository); assertSame(1, bean.stringRepositoryArray.length); @@ -1287,6 +1287,74 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertSame(ir, bean.integerRepositoryMap.get("integerRepo")); } + @Test + public void testGenericsBasedFieldInjectionWithSimpleMatch() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSimpleMatch.class); + bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + bf.registerBeanDefinition("annotatedBean", bd); + + bf.registerSingleton("repo", new StringRepository()); + + RepositoryFieldInjectionBeanWithSimpleMatch bean = (RepositoryFieldInjectionBeanWithSimpleMatch) bf.getBean("annotatedBean"); + Repository repo = bf.getBean("repo", Repository.class); + assertSame(repo, bean.repository); + assertSame(repo, bean.stringRepository); + assertSame(1, bean.repositoryArray.length); + assertSame(1, bean.stringRepositoryArray.length); + assertSame(repo, bean.repositoryArray[0]); + assertSame(repo, bean.stringRepositoryArray[0]); + assertSame(1, bean.repositoryList.size()); + assertSame(1, bean.stringRepositoryList.size()); + assertSame(repo, bean.repositoryList.get(0)); + assertSame(repo, bean.stringRepositoryList.get(0)); + assertSame(1, bean.repositoryMap.size()); + assertSame(1, bean.stringRepositoryMap.size()); + assertSame(repo, bean.repositoryMap.get("repo")); + assertSame(repo, bean.stringRepositoryMap.get("repo")); + } + + @Test + public void testGenericsBasedFieldInjectionWithSimpleMatchAndMock() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + RootBeanDefinition bd = new RootBeanDefinition(RepositoryFieldInjectionBeanWithSimpleMatch.class); + bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + bf.registerBeanDefinition("annotatedBean", bd); + + RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class); + bf.registerBeanDefinition("mocksControl", rbd); + rbd = new RootBeanDefinition(); + rbd.setFactoryBeanName("mocksControl"); + rbd.setFactoryMethodName("createMock"); + rbd.getConstructorArgumentValues().addGenericArgumentValue(Repository.class); + bf.registerBeanDefinition("repo", rbd); + + RepositoryFieldInjectionBeanWithSimpleMatch bean = (RepositoryFieldInjectionBeanWithSimpleMatch) bf.getBean("annotatedBean"); + Repository repo = bf.getBean("repo", Repository.class); + assertSame(repo, bean.repository); + assertSame(repo, bean.stringRepository); + assertSame(1, bean.repositoryArray.length); + assertSame(1, bean.stringRepositoryArray.length); + assertSame(repo, bean.repositoryArray[0]); + assertSame(repo, bean.stringRepositoryArray[0]); + assertSame(1, bean.repositoryList.size()); + assertSame(1, bean.stringRepositoryList.size()); + assertSame(repo, bean.repositoryList.get(0)); + assertSame(repo, bean.stringRepositoryList.get(0)); + assertSame(1, bean.repositoryMap.size()); + assertSame(1, bean.stringRepositoryMap.size()); + assertSame(repo, bean.repositoryMap.get("repo")); + assertSame(repo, bean.stringRepositoryMap.get("repo")); + } + @Test public void testGenericsBasedMethodInjection() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); @@ -2163,6 +2231,34 @@ public class AutowiredAnnotationBeanPostProcessorTests { } + public static class RepositoryFieldInjectionBeanWithSimpleMatch { + + @Autowired + public Repository repository; + + @Autowired + public Repository stringRepository; + + @Autowired + public Repository[] repositoryArray; + + @Autowired + public Repository[] stringRepositoryArray; + + @Autowired + public List repositoryList; + + @Autowired + public List> stringRepositoryList; + + @Autowired + public Map> repositoryMap; + + @Autowired + public Map> stringRepositoryMap; + } + + public static class RepositoryMethodInjectionBean { public Repository stringRepository; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 31306113359..23f090d019c 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -154,6 +154,17 @@ public class ConfigurationClassPostProcessorTests { assertSame(bf.getBean("integerRepo"), bean.integerRepository); } + @Test + public void testGenericsBasedInjectionWithRawMatch() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); + bf.registerBeanDefinition("configClass", new RootBeanDefinition(RawMatchingConfiguration.class)); + ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); + pp.postProcessBeanFactory(bf); + + assertSame(bf.getBean("repo"), bf.getBean("repoConsumer")); + } + @Configuration static class SingletonBeanConfig { @@ -173,13 +184,18 @@ public class ConfigurationClassPostProcessorTests { static class Bar { + final Foo foo; - public Bar(Foo foo) { this.foo = foo; } + + public Bar(Foo foo) { + this.foo = foo; + } } @Configuration static class UnloadedConfig { + public @Bean Foo foo() { return new Foo(); } @@ -188,13 +204,14 @@ public class ConfigurationClassPostProcessorTests { @Configuration static class LoadedConfig { + public @Bean Bar bar() { return new Bar(new Foo()); } } - public interface Repository { + public static class Repository { } @@ -213,14 +230,27 @@ public class ConfigurationClassPostProcessorTests { @Bean public Repository stringRepo() { - return new Repository() { - }; + return new Repository(); } @Bean public Repository integerRepo() { - return new Repository() { - }; + return new Repository(); + } + } + + + @Configuration + public static class RawMatchingConfiguration { + + @Bean + public Repository repo() { + return new Repository(); + } + + @Bean + public Object repoConsumer(Repository repo) { + return repo; } }