|
|
|
@ -405,33 +405,31 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
else { |
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
return parentBeanFactory.isSingleton(originalBeanName(name)); |
|
|
|
return parentBeanFactory.isSingleton(originalBeanName(name)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
|
|
|
|
|
|
|
|
// In case of FactoryBean, return singleton status of created object if not a dereference.
|
|
|
|
// In case of FactoryBean, return singleton status of created object if not a dereference.
|
|
|
|
if (mbd.isSingleton()) { |
|
|
|
if (mbd.isSingleton()) { |
|
|
|
if (isFactoryBean(beanName, mbd)) { |
|
|
|
if (isFactoryBean(beanName, mbd)) { |
|
|
|
if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
|
|
|
|
return factoryBean.isSingleton(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return !BeanFactoryUtils.isFactoryDereference(name); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
|
|
|
|
return factoryBean.isSingleton(); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
return false; |
|
|
|
return !BeanFactoryUtils.isFactoryDereference(name); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -449,32 +447,31 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp |
|
|
|
// In case of FactoryBean, return singleton status of created object if not a dereference.
|
|
|
|
// In case of FactoryBean, return singleton status of created object if not a dereference.
|
|
|
|
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd)); |
|
|
|
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd)); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
// Singleton or scoped - not a prototype.
|
|
|
|
// Singleton or scoped - not a prototype.
|
|
|
|
// However, FactoryBean may still produce a prototype object...
|
|
|
|
// However, FactoryBean may still produce a prototype object...
|
|
|
|
if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (isFactoryBean(beanName, mbd)) { |
|
|
|
if (isFactoryBean(beanName, mbd)) { |
|
|
|
final FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
final FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
if (System.getSecurityManager() != null) { |
|
|
|
if (System.getSecurityManager() != null) { |
|
|
|
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
|
|
|
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Boolean run() { |
|
|
|
public Boolean run() { |
|
|
|
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || |
|
|
|
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || |
|
|
|
!fb.isSingleton()); |
|
|
|
!fb.isSingleton()); |
|
|
|
} |
|
|
|
} |
|
|
|
}, getAccessControlContext()); |
|
|
|
}, getAccessControlContext()); |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || |
|
|
|
|
|
|
|
!fb.isSingleton()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
return false; |
|
|
|
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || |
|
|
|
|
|
|
|
!fb.isSingleton()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -493,78 +490,91 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp |
|
|
|
return typeToMatch.isInstance(beanInstance); |
|
|
|
return typeToMatch.isInstance(beanInstance); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else if (!BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
return (!BeanFactoryUtils.isFactoryDereference(name) && typeToMatch.isInstance(beanInstance)); |
|
|
|
if (typeToMatch.isInstance(beanInstance)) { |
|
|
|
|
|
|
|
// Direct match for exposed instance?
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) { |
|
|
|
|
|
|
|
// Generics potentially only match on the target class, not on the proxy...
|
|
|
|
|
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
|
|
|
|
Class<?> targetType = mbd.getTargetType(); |
|
|
|
|
|
|
|
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance) && |
|
|
|
|
|
|
|
typeToMatch.isAssignableFrom(targetType)) { |
|
|
|
|
|
|
|
// Check raw class match as well, making sure it's exposed on the proxy.
|
|
|
|
|
|
|
|
Class<?> classToMatch = typeToMatch.resolve(); |
|
|
|
|
|
|
|
return (classToMatch == null || classToMatch.isInstance(beanInstance)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) { |
|
|
|
else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) { |
|
|
|
// null instance registered
|
|
|
|
// null instance registered
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
else { |
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch); |
|
|
|
return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieve corresponding bean definition.
|
|
|
|
// Retrieve corresponding bean definition.
|
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
|
|
|
|
|
|
|
|
Class<?> classToMatch = typeToMatch.resolve(); |
|
|
|
Class<?> classToMatch = typeToMatch.resolve(); |
|
|
|
if (classToMatch == null) { |
|
|
|
if (classToMatch == null) { |
|
|
|
classToMatch = FactoryBean.class; |
|
|
|
classToMatch = FactoryBean.class; |
|
|
|
} |
|
|
|
} |
|
|
|
Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ? |
|
|
|
Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ? |
|
|
|
new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch}); |
|
|
|
new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch}); |
|
|
|
|
|
|
|
|
|
|
|
// Check decorated bean definition, if any: We assume it'll be easier
|
|
|
|
// Check decorated bean definition, if any: We assume it'll be easier
|
|
|
|
// to determine the decorated bean's type than the proxy's type.
|
|
|
|
// to determine the decorated bean's type than the proxy's type.
|
|
|
|
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); |
|
|
|
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); |
|
|
|
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); |
|
|
|
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); |
|
|
|
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch); |
|
|
|
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch); |
|
|
|
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { |
|
|
|
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { |
|
|
|
return typeToMatch.isAssignableFrom(targetClass); |
|
|
|
return typeToMatch.isAssignableFrom(targetClass); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch); |
|
|
|
Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch); |
|
|
|
if (beanType == null) { |
|
|
|
if (beanType == null) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check bean class whether we're dealing with a FactoryBean.
|
|
|
|
// Check bean class whether we're dealing with a FactoryBean.
|
|
|
|
if (FactoryBean.class.isAssignableFrom(beanType)) { |
|
|
|
if (FactoryBean.class.isAssignableFrom(beanType)) { |
|
|
|
if (!BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (!BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
|
|
|
|
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
|
|
|
|
beanType = getTypeForFactoryBean(beanName, mbd); |
|
|
|
beanType = getTypeForFactoryBean(beanName, mbd); |
|
|
|
if (beanType == null) { |
|
|
|
if (beanType == null) { |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
|
|
|
|
// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
|
|
|
|
|
|
|
|
// type but we nevertheless are being asked to dereference a FactoryBean...
|
|
|
|
|
|
|
|
// Let's check the original bean class and proceed with it if it is a FactoryBean.
|
|
|
|
|
|
|
|
beanType = predictBeanType(beanName, mbd, FactoryBean.class); |
|
|
|
|
|
|
|
if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) { |
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
ResolvableType resolvableType = mbd.targetType; |
|
|
|
else if (BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (resolvableType == null) { |
|
|
|
// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
|
|
|
|
resolvableType = mbd.factoryMethodReturnType; |
|
|
|
// type but we nevertheless are being asked to dereference a FactoryBean...
|
|
|
|
} |
|
|
|
// Let's check the original bean class and proceed with it if it is a FactoryBean.
|
|
|
|
if (resolvableType != null && resolvableType.resolve() == beanType) { |
|
|
|
beanType = predictBeanType(beanName, mbd, FactoryBean.class); |
|
|
|
return typeToMatch.isAssignableFrom(resolvableType); |
|
|
|
if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) { |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return typeToMatch.isAssignableFrom(beanType); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ResolvableType resolvableType = mbd.targetType; |
|
|
|
|
|
|
|
if (resolvableType == null) { |
|
|
|
|
|
|
|
resolvableType = mbd.factoryMethodReturnType; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (resolvableType != null && resolvableType.resolve() == beanType) { |
|
|
|
|
|
|
|
return typeToMatch.isAssignableFrom(resolvableType); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return typeToMatch.isAssignableFrom(beanType); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -591,43 +601,41 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
else { |
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
// No singleton instance found -> check bean definition.
|
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
BeanFactory parentBeanFactory = getParentBeanFactory(); |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { |
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
// No bean definition found in this factory -> delegate to parent.
|
|
|
|
return parentBeanFactory.getType(originalBeanName(name)); |
|
|
|
return parentBeanFactory.getType(originalBeanName(name)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); |
|
|
|
|
|
|
|
|
|
|
|
// Check decorated bean definition, if any: We assume it'll be easier
|
|
|
|
// Check decorated bean definition, if any: We assume it'll be easier
|
|
|
|
// to determine the decorated bean's type than the proxy's type.
|
|
|
|
// to determine the decorated bean's type than the proxy's type.
|
|
|
|
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); |
|
|
|
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); |
|
|
|
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); |
|
|
|
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); |
|
|
|
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd); |
|
|
|
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd); |
|
|
|
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { |
|
|
|
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { |
|
|
|
return targetClass; |
|
|
|
return targetClass; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Class<?> beanClass = predictBeanType(beanName, mbd); |
|
|
|
Class<?> beanClass = predictBeanType(beanName, mbd); |
|
|
|
|
|
|
|
|
|
|
|
// Check bean class whether we're dealing with a FactoryBean.
|
|
|
|
// Check bean class whether we're dealing with a FactoryBean.
|
|
|
|
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { |
|
|
|
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { |
|
|
|
if (!BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
if (!BeanFactoryUtils.isFactoryDereference(name)) { |
|
|
|
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
|
|
|
|
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
|
|
|
|
return getTypeForFactoryBean(beanName, mbd); |
|
|
|
return getTypeForFactoryBean(beanName, mbd); |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return beanClass; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null); |
|
|
|
return beanClass; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
|