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 8c972e4fc9..c476f6e916 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 @@ -548,15 +548,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException { - // Consider FactoryBeans as autowiring candidates. - boolean isFactoryBean = (descriptor != null && descriptor.getDependencyType() != null && - FactoryBean.class.isAssignableFrom(descriptor.getDependencyType())); - if (isFactoryBean) { - beanName = BeanFactoryUtils.transformedBeanName(beanName); - } - - if (containsBeanDefinition(beanName)) { - return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanName), descriptor); + String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); + if (containsBeanDefinition(beanDefinitionName)) { + return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor); } else if (containsSingleton(beanName)) { return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor); @@ -579,7 +573,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto * @return whether the bean should be considered as autowire candidate */ protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor) { - resolveBeanClass(mbd, beanName); + String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); + resolveBeanClass(mbd, beanDefinitionName); if (mbd.isFactoryMethodUnique) { boolean resolve; synchronized (mbd.constructorArgumentLock) { @@ -590,7 +585,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } } return getAutowireCandidateResolver().isAutowireCandidate( - new BeanDefinitionHolder(mbd, beanName, getAliases(beanName)), descriptor); + new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor); } @Override 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 3c4d474047..9e1e9eb49e 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 @@ -1320,6 +1320,40 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertSame(repo, bean.stringRepositoryMap.get("repo")); } + @Test + public void testGenericsBasedFactoryBeanInjectionWithBeanDefinition() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class); + bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + bf.registerBeanDefinition("annotatedBean", bd); + bf.registerBeanDefinition("repoFactoryBean", new RootBeanDefinition(RepositoryFactoryBean.class)); + + RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean"); + RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class); + assertSame(repoFactoryBean, bean.repositoryFactoryBean); + } + + @Test + public void testGenericsBasedFactoryBeanInjectionWithSingletonBean() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); + AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); + bpp.setBeanFactory(bf); + bf.addBeanPostProcessor(bpp); + RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class); + bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + bf.registerBeanDefinition("annotatedBean", bd); + bf.registerSingleton("repoFactoryBean", new RepositoryFactoryBean<>()); + + RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean"); + RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class); + assertSame(repoFactoryBean, bean.repositoryFactoryBean); + } + @Test public void testGenericsBasedFieldInjectionWithSimpleMatchAndMock() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); @@ -2180,6 +2214,25 @@ public class AutowiredAnnotationBeanPostProcessorTests { } + public static class RepositoryFactoryBean implements FactoryBean { + + @Override + public T getObject() { + throw new IllegalStateException(); + } + + @Override + public Class getObjectType() { + return Object.class; + } + + @Override + public boolean isSingleton() { + return false; + } + } + + public static class RepositoryFieldInjectionBean { @Autowired @@ -2297,6 +2350,13 @@ public class AutowiredAnnotationBeanPostProcessorTests { } + public static class RepositoryFactoryBeanInjectionBean { + + @Autowired + public RepositoryFactoryBean repositoryFactoryBean; + } + + public static class RepositoryMethodInjectionBean { public Repository stringRepository;