From 73fa7089052810809353dbfd14a893b2d444740b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 9 Jan 2026 19:33:32 +0100 Subject: [PATCH] Fix SmartFactoryBean type matching for ResolvableType.NONE Closes gh-36123 --- .../beans/factory/support/AbstractBeanFactory.java | 4 ++-- .../beans/factory/support/StaticListableBeanFactory.java | 9 +++++---- .../beans/factory/BeanFactoryUtilsTests.java | 5 +++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index d44f96017e5..54a5921b546 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -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()); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index 3b2c5e9c189..87fbc1a2751 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -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 matches = new ArrayList<>(); for (Map.Entry 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); } } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/BeanFactoryUtilsTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/BeanFactoryUtilsTests.java index 4ab5ced5b1b..7593496f052 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/BeanFactoryUtilsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/BeanFactoryUtilsTests.java @@ -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