Skip to content

Commit 148f8f0

Browse files
committed
AutowireCandidateResolver receives original bean name (including FactoryBean prefix if applicable) for correct generic type check in case of a FactoryBean definition
Issue: SPR-11045
1 parent f958418 commit 148f8f0

File tree

2 files changed

+66
-11
lines changed

2 files changed

+66
-11
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -548,15 +548,9 @@ public void registerResolvableDependency(Class<?> dependencyType, Object autowir
548548
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
549549
throws NoSuchBeanDefinitionException {
550550

551-
// Consider FactoryBeans as autowiring candidates.
552-
boolean isFactoryBean = (descriptor != null && descriptor.getDependencyType() != null &&
553-
FactoryBean.class.isAssignableFrom(descriptor.getDependencyType()));
554-
if (isFactoryBean) {
555-
beanName = BeanFactoryUtils.transformedBeanName(beanName);
556-
}
557-
558-
if (containsBeanDefinition(beanName)) {
559-
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanName), descriptor);
551+
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
552+
if (containsBeanDefinition(beanDefinitionName)) {
553+
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor);
560554
}
561555
else if (containsSingleton(beanName)) {
562556
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor);
@@ -579,7 +573,8 @@ else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) {
579573
* @return whether the bean should be considered as autowire candidate
580574
*/
581575
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor) {
582-
resolveBeanClass(mbd, beanName);
576+
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
577+
resolveBeanClass(mbd, beanDefinitionName);
583578
if (mbd.isFactoryMethodUnique) {
584579
boolean resolve;
585580
synchronized (mbd.constructorArgumentLock) {
@@ -590,7 +585,7 @@ protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, D
590585
}
591586
}
592587
return getAutowireCandidateResolver().isAutowireCandidate(
593-
new BeanDefinitionHolder(mbd, beanName, getAliases(beanName)), descriptor);
588+
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
594589
}
595590

596591
@Override

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,40 @@ public void testGenericsBasedFieldInjectionWithSimpleMatch() {
13201320
assertSame(repo, bean.stringRepositoryMap.get("repo"));
13211321
}
13221322

1323+
@Test
1324+
public void testGenericsBasedFactoryBeanInjectionWithBeanDefinition() {
1325+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1326+
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1327+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1328+
bpp.setBeanFactory(bf);
1329+
bf.addBeanPostProcessor(bpp);
1330+
RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
1331+
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1332+
bf.registerBeanDefinition("annotatedBean", bd);
1333+
bf.registerBeanDefinition("repoFactoryBean", new RootBeanDefinition(RepositoryFactoryBean.class));
1334+
1335+
RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean");
1336+
RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class);
1337+
assertSame(repoFactoryBean, bean.repositoryFactoryBean);
1338+
}
1339+
1340+
@Test
1341+
public void testGenericsBasedFactoryBeanInjectionWithSingletonBean() {
1342+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1343+
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
1344+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1345+
bpp.setBeanFactory(bf);
1346+
bf.addBeanPostProcessor(bpp);
1347+
RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
1348+
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
1349+
bf.registerBeanDefinition("annotatedBean", bd);
1350+
bf.registerSingleton("repoFactoryBean", new RepositoryFactoryBean<>());
1351+
1352+
RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) bf.getBean("annotatedBean");
1353+
RepositoryFactoryBean repoFactoryBean = bf.getBean("&repoFactoryBean", RepositoryFactoryBean.class);
1354+
assertSame(repoFactoryBean, bean.repositoryFactoryBean);
1355+
}
1356+
13231357
@Test
13241358
public void testGenericsBasedFieldInjectionWithSimpleMatchAndMock() {
13251359
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -2180,6 +2214,25 @@ public static class SimpleRepositorySubclass extends SimpleRepository {
21802214
}
21812215

21822216

2217+
public static class RepositoryFactoryBean<T> implements FactoryBean<T> {
2218+
2219+
@Override
2220+
public T getObject() {
2221+
throw new IllegalStateException();
2222+
}
2223+
2224+
@Override
2225+
public Class<?> getObjectType() {
2226+
return Object.class;
2227+
}
2228+
2229+
@Override
2230+
public boolean isSingleton() {
2231+
return false;
2232+
}
2233+
}
2234+
2235+
21832236
public static class RepositoryFieldInjectionBean {
21842237

21852238
@Autowired
@@ -2297,6 +2350,13 @@ public static class RepositoryFieldInjectionBeanWithSimpleMatch {
22972350
}
22982351

22992352

2353+
public static class RepositoryFactoryBeanInjectionBean {
2354+
2355+
@Autowired
2356+
public RepositoryFactoryBean<?> repositoryFactoryBean;
2357+
}
2358+
2359+
23002360
public static class RepositoryMethodInjectionBean {
23012361

23022362
public Repository<String> stringRepository;

0 commit comments

Comments
 (0)