Fix SmartFactoryBean type matching for ResolvableType.NONE

Closes gh-36123
This commit is contained in:
Juergen Hoeller
2026-01-09 19:33:32 +01:00
parent 23a532ed82
commit 73fa708905
3 changed files with 12 additions and 6 deletions
@@ -535,8 +535,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Determine target for FactoryBean match if necessary.
if (beanInstance instanceof FactoryBean<?> factoryBean) {
if (!isFactoryDereference) {
Class<?> classToMatch = typeToMatch.resolve();
if (factoryBean instanceof SmartFactoryBean<?> smartFactoryBean &&
smartFactoryBean.supportsType(typeToMatch.toClass())) {
classToMatch != null && smartFactoryBean.supportsType(classToMatch)) {
return true;
}
Class<?> type = getTypeForFactoryBean(factoryBean);
@@ -557,7 +558,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
Class<?> targetClass = targetType.resolve();
if (targetClass != null && FactoryBean.class.isAssignableFrom(targetClass)) {
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch != null && !FactoryBean.class.isAssignableFrom(classToMatch) &&
!classToMatch.isAssignableFrom(targetType.toClass())) {
return typeToMatch.isAssignableFrom(targetType.getGeneric());
@@ -234,7 +234,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
String beanName = BeanFactoryUtils.transformedBeanName(name);
Object bean = obtainBean(beanName);
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
return isTypeMatch(factoryBean, typeToMatch.toClass());
Class<?> classToMatch = typeToMatch.resolve();
return (classToMatch != null && isTypeMatch(factoryBean, classToMatch));
}
return typeToMatch.isInstance(bean);
}
@@ -372,8 +373,8 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
public String[] getBeanNamesForType(@Nullable ResolvableType type,
boolean includeNonSingletons, boolean allowEagerInit) {
Class<?> resolved = (type != null ? type.resolve() : null);
boolean isFactoryType = (resolved != null && FactoryBean.class.isAssignableFrom(resolved));
Class<?> clazz = (type != null ? type.resolve() : null);
boolean isFactoryType = (clazz != null && FactoryBean.class.isAssignableFrom(clazz));
List<String> matches = new ArrayList<>();
for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
@@ -381,7 +382,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
Object beanInstance = entry.getValue();
if (beanInstance instanceof FactoryBean<?> factoryBean && !isFactoryType) {
if ((includeNonSingletons || factoryBean.isSingleton()) &&
(type == null || isTypeMatch(factoryBean, type.toClass()))) {
(type == null || (clazz != null && isTypeMatch(factoryBean, clazz)))) {
matches.add(beanName);
}
}
@@ -38,6 +38,7 @@ import org.springframework.beans.testfixture.beans.TestAnnotation;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.beans.testfixture.beans.factory.DummyFactory;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.io.Resource;
import org.springframework.util.ObjectUtils;
@@ -552,6 +553,10 @@ class BeanFactoryUtilsTests {
assertThat(lbf.getBean("sfb2", CharSequence.class)).isInstanceOf(String.class);
assertThat(lbf.getBean("sfb1")).isInstanceOf(String.class);
assertThat(lbf.getBean("sfb2")).isInstanceOf(String.class);
assertThat(lbf.getBeanNamesForType(Object.class)).isNotEmpty();
assertThat(lbf.getBeanNamesForType(ResolvableType.forClass(Object.class))).isNotEmpty();
assertThat(lbf.getBeanNamesForType(ResolvableType.NONE)).isEmpty();
}
@Test