Skip to content

Commit 2232890

Browse files
committed
Do not extract FactoryBean generic in case of targetType mismatch
Closes gh-32489
1 parent 67a8100 commit 2232890

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -108,7 +108,8 @@ protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, Dependenc
108108
Class<?> resolvedClass = targetType.resolve();
109109
if (resolvedClass != null && FactoryBean.class.isAssignableFrom(resolvedClass)) {
110110
Class<?> typeToBeMatched = dependencyType.resolve();
111-
if (typeToBeMatched != null && !FactoryBean.class.isAssignableFrom(typeToBeMatched)) {
111+
if (typeToBeMatched != null && !FactoryBean.class.isAssignableFrom(typeToBeMatched) &&
112+
!typeToBeMatched.isAssignableFrom(resolvedClass)) {
112113
targetType = targetType.getGeneric();
113114
if (descriptor.fallbackMatchAllowed()) {
114115
// Matching the Class-based type determination for FactoryBean

spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java

+46
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.mockito.Mockito;
3333

3434
import org.springframework.beans.factory.BeanCreationException;
35+
import org.springframework.beans.factory.FactoryBean;
3536
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
3637
import org.springframework.beans.factory.ObjectProvider;
3738
import org.springframework.beans.factory.config.TypedStringValue;
@@ -850,6 +851,23 @@ void genericMatchingWithUnresolvedOrderedStream() {
850851
bf.getBean("store2", NumberStore.class), bf.getBean("store1", NumberStore.class));
851852
}
852853

854+
@Test // gh-32489
855+
void genericMatchingAgainstFactoryBeanClass() {
856+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
857+
bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver());
858+
859+
RootBeanDefinition bd = new RootBeanDefinition(MyFactoryBean.class);
860+
// Replicate org.springframework.data.repository.config.RepositoryConfigurationDelegate#registerRepositoriesIn
861+
// behavior of setting targetType, required to hit other branch in
862+
// org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver.checkGenericTypeMatch
863+
bd.setTargetType(ResolvableType.forClassWithGenerics(MyFactoryBean.class, String.class));
864+
bf.registerBeanDefinition("myFactoryBean", bd);
865+
bf.registerBeanDefinition("myFactoryBeanHolder",
866+
new RootBeanDefinition(MyFactoryBeanHolder.class, AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR, false));
867+
868+
assertThat(bf.getBean(MyFactoryBeanHolder.class).factoryBeans).contains(bf.getBean(MyFactoryBean.class));
869+
}
870+
853871

854872
/**
855873
* Mimics and delegates to {@link Mockito#mock(Class)} -- created here to avoid factory
@@ -966,4 +984,32 @@ public static NumberStore<Float> newFloatStore() {
966984
}
967985
}
968986

987+
988+
public interface MyGenericInterfaceForFactoryBeans<T> {
989+
}
990+
991+
992+
public static class MyFactoryBean<T extends CharSequence> implements FactoryBean<T>, MyGenericInterfaceForFactoryBeans<T> {
993+
994+
@Override
995+
public T getObject() {
996+
throw new UnsupportedOperationException();
997+
}
998+
999+
@Override
1000+
public Class<?> getObjectType() {
1001+
return String.class;
1002+
}
1003+
}
1004+
1005+
1006+
public static class MyFactoryBeanHolder {
1007+
1008+
List<MyGenericInterfaceForFactoryBeans<?>> factoryBeans; // Requested type is not a FactoryBean type
1009+
1010+
public MyFactoryBeanHolder(List<MyGenericInterfaceForFactoryBeans<?>> factoryBeans) {
1011+
this.factoryBeans = factoryBeans;
1012+
}
1013+
}
1014+
9691015
}

0 commit comments

Comments
 (0)