Avoid repeated FactoryBean targetType check

See gh-30987
This commit is contained in:
Juergen Hoeller 2023-08-04 00:47:04 +02:00
parent 4b6fabbd2f
commit 9333ed22f6
3 changed files with 45 additions and 38 deletions

View File

@ -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;
}
/**

View File

@ -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;
}

View File

@ -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.