AutowireCandidateResolver receives original bean name (including FactoryBean prefix if applicable) for correct generic type check in case of a FactoryBean definition

Issue: SPR-11045
master
Juergen Hoeller 11 years ago
parent f9584184ef
commit 148f8f011d
  1. 17
      spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
  2. 60
      spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.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

@ -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<T> implements FactoryBean<T> {
@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<String> stringRepository;

Loading…
Cancel
Save