From 9333ed22f6ea6fae9909f6b6e6aa317c1b45ce82 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 4 Aug 2023 00:47:04 +0200 Subject: [PATCH] Avoid repeated FactoryBean targetType check See gh-30987 --- .../AbstractAutowireCapableBeanFactory.java | 33 ++++++++----------- .../factory/support/AbstractBeanFactory.java | 20 +---------- .../support/FactoryBeanRegistrySupport.java | 30 +++++++++++++++++ 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 667969ed83..7de716b44c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -837,16 +837,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac return result; } - ResolvableType beanType = - (mbd.hasBeanClass() ? ResolvableType.forClass(mbd.getBeanClass()) : ResolvableType.NONE); - - // For instance supplied beans try the target type and bean class + // For instance supplied beans, try the target type and bean class immediately if (mbd.getInstanceSupplier() != null) { result = getFactoryBeanGeneric(mbd.targetType); if (result.resolve() != null) { return result; } - result = getFactoryBeanGeneric(beanType); + result = getFactoryBeanGeneric(mbd.hasBeanClass() ? ResolvableType.forClass(mbd.getBeanClass()) : null); if (result.resolve() != null) { return result; } @@ -909,22 +906,20 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac return getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName); } - result = getFactoryBeanGeneric(mbd.targetType); - if (result.resolve() != null) { - return result; + // For regular beans, try the target type and bean class as fallback + if (mbd.getInstanceSupplier() == null) { + result = getFactoryBeanGeneric(mbd.targetType); + if (result.resolve() != null) { + return result; + } + result = getFactoryBeanGeneric(mbd.hasBeanClass() ? ResolvableType.forClass(mbd.getBeanClass()) : null); + if (result.resolve() != null) { + return result; + } } - result = getFactoryBeanGeneric(beanType); - if (result.resolve() != null) { - return result; - } - return ResolvableType.NONE; - } - private ResolvableType getFactoryBeanGeneric(@Nullable ResolvableType type) { - if (type == null) { - return ResolvableType.NONE; - } - return type.as(FactoryBean.class).getGeneric(); + // FactoryBean type not resolvable + return ResolvableType.NONE; } /** 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 c0f9bb5868..57b9b8dffa 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 @@ -64,7 +64,6 @@ import org.springframework.beans.factory.config.DestructionAwareBeanPostProcesso import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; -import org.springframework.core.AttributeAccessor; import org.springframework.core.DecoratingClassLoader; import org.springframework.core.NamedThreadLocal; import org.springframework.core.ResolvableType; @@ -1684,25 +1683,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp onSuppressedException(ex); } } - return ResolvableType.NONE; - } - /** - * Determine the bean type for a FactoryBean by inspecting its attributes for a - * {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} value. - * @param attributes the attributes to inspect - * @return a {@link ResolvableType} extracted from the attributes or - * {@code ResolvableType.NONE} - * @since 5.2 - */ - ResolvableType getTypeForFactoryBeanFromAttributes(AttributeAccessor attributes) { - Object attribute = attributes.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE); - if (attribute instanceof ResolvableType resolvableType) { - return resolvableType; - } - if (attribute instanceof Class clazz) { - return ResolvableType.forClass(clazz); - } + // FactoryBean type not resolvable return ResolvableType.NONE; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java index bfe5820390..72644917ea 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java @@ -24,6 +24,8 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBeanNotInitializedException; +import org.springframework.core.AttributeAccessor; +import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; /** @@ -61,6 +63,34 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg } } + /** + * Determine the bean type for a FactoryBean by inspecting its attributes for a + * {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} value. + * @param attributes the attributes to inspect + * @return a {@link ResolvableType} extracted from the attributes or + * {@code ResolvableType.NONE} + * @since 5.2 + */ + ResolvableType getTypeForFactoryBeanFromAttributes(AttributeAccessor attributes) { + Object attribute = attributes.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE); + if (attribute instanceof ResolvableType resolvableType) { + return resolvableType; + } + if (attribute instanceof Class clazz) { + return ResolvableType.forClass(clazz); + } + return ResolvableType.NONE; + } + + /** + * Determine the FactoryBean object type from the given generic declaration. + * @param type the FactoryBean type + * @return the nested object type, or {@code NONE} if not resolvable + */ + ResolvableType getFactoryBeanGeneric(@Nullable ResolvableType type) { + return (type != null ? type.as(FactoryBean.class).getGeneric() : ResolvableType.NONE); + } + /** * Obtain an object to expose from the given FactoryBean, if available * in cached form. Quick check for minimal synchronization.