|
|
|
@ -58,6 +58,7 @@ import org.springframework.beans.factory.BeanFactoryAware; |
|
|
|
import org.springframework.beans.factory.BeanFactoryUtils; |
|
|
|
import org.springframework.beans.factory.BeanFactoryUtils; |
|
|
|
import org.springframework.beans.factory.BeanNotOfRequiredTypeException; |
|
|
|
import org.springframework.beans.factory.BeanNotOfRequiredTypeException; |
|
|
|
import org.springframework.beans.factory.CannotLoadBeanClassException; |
|
|
|
import org.springframework.beans.factory.CannotLoadBeanClassException; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.FactoryBean; |
|
|
|
import org.springframework.beans.factory.InjectionPoint; |
|
|
|
import org.springframework.beans.factory.InjectionPoint; |
|
|
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
|
|
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
|
|
|
import org.springframework.beans.factory.NoUniqueBeanDefinitionException; |
|
|
|
import org.springframework.beans.factory.NoUniqueBeanDefinitionException; |
|
|
|
@ -196,8 +197,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
/** Map from bean name to merged BeanDefinitionHolder. */ |
|
|
|
/** Map from bean name to merged BeanDefinitionHolder. */ |
|
|
|
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256); |
|
|
|
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256); |
|
|
|
|
|
|
|
|
|
|
|
/** Set of bean definition names with a primary marker. */ |
|
|
|
/** Map of bean definition names with a primary marker plus corresponding type. */ |
|
|
|
private final Set<String> primaryBeanNames = ConcurrentHashMap.newKeySet(16); |
|
|
|
private final Map<String, Class<?>> primaryBeanNamesWithType = new ConcurrentHashMap<>(16); |
|
|
|
|
|
|
|
|
|
|
|
/** Map of singleton and non-singleton bean names, keyed by dependency type. */ |
|
|
|
/** Map of singleton and non-singleton bean names, keyed by dependency type. */ |
|
|
|
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); |
|
|
|
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); |
|
|
|
@ -1037,7 +1038,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
protected void cacheMergedBeanDefinition(RootBeanDefinition mbd, String beanName) { |
|
|
|
protected void cacheMergedBeanDefinition(RootBeanDefinition mbd, String beanName) { |
|
|
|
super.cacheMergedBeanDefinition(mbd, beanName); |
|
|
|
super.cacheMergedBeanDefinition(mbd, beanName); |
|
|
|
if (mbd.isPrimary()) { |
|
|
|
if (mbd.isPrimary()) { |
|
|
|
this.primaryBeanNames.add(beanName); |
|
|
|
this.primaryBeanNamesWithType.put(beanName, Void.class); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1313,7 +1314,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
|
|
|
|
|
|
|
|
// Cache a primary marker for the given bean.
|
|
|
|
// Cache a primary marker for the given bean.
|
|
|
|
if (beanDefinition.isPrimary()) { |
|
|
|
if (beanDefinition.isPrimary()) { |
|
|
|
this.primaryBeanNames.add(beanName); |
|
|
|
this.primaryBeanNamesWithType.put(beanName, Void.class); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1405,7 +1406,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
destroySingleton(beanName); |
|
|
|
destroySingleton(beanName); |
|
|
|
|
|
|
|
|
|
|
|
// Remove a cached primary marker for the given bean.
|
|
|
|
// Remove a cached primary marker for the given bean.
|
|
|
|
this.primaryBeanNames.remove(beanName); |
|
|
|
this.primaryBeanNamesWithType.remove(beanName); |
|
|
|
|
|
|
|
|
|
|
|
// Notify all post-processors that the specified bean definition has been reset.
|
|
|
|
// Notify all post-processors that the specified bean definition has been reset.
|
|
|
|
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) { |
|
|
|
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) { |
|
|
|
@ -1458,9 +1459,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected void addSingleton(String beanName, Object singletonObject) { |
|
|
|
protected void addSingleton(String beanName, Object singletonObject) { |
|
|
|
super.addSingleton(beanName, singletonObject); |
|
|
|
super.addSingleton(beanName, singletonObject); |
|
|
|
|
|
|
|
|
|
|
|
Predicate<Class<?>> filter = (beanType -> beanType != Object.class && beanType.isInstance(singletonObject)); |
|
|
|
Predicate<Class<?>> filter = (beanType -> beanType != Object.class && beanType.isInstance(singletonObject)); |
|
|
|
this.allBeanNamesByType.keySet().removeIf(filter); |
|
|
|
this.allBeanNamesByType.keySet().removeIf(filter); |
|
|
|
this.singletonBeanNamesByType.keySet().removeIf(filter); |
|
|
|
this.singletonBeanNamesByType.keySet().removeIf(filter); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.primaryBeanNamesWithType.containsKey(beanName) && singletonObject.getClass() != NullBean.class) { |
|
|
|
|
|
|
|
Class<?> beanType = (singletonObject instanceof FactoryBean<?> fb ? |
|
|
|
|
|
|
|
getTypeForFactoryBean(fb) : singletonObject.getClass()); |
|
|
|
|
|
|
|
if (beanType != null) { |
|
|
|
|
|
|
|
this.primaryBeanNamesWithType.put(beanName, beanType); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -2268,8 +2278,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
* not matching the given bean name. |
|
|
|
* not matching the given bean name. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private boolean hasPrimaryConflict(String beanName, Class<?> dependencyType) { |
|
|
|
private boolean hasPrimaryConflict(String beanName, Class<?> dependencyType) { |
|
|
|
for (String candidate : this.primaryBeanNames) { |
|
|
|
for (Map.Entry<String, Class<?>> candidate : this.primaryBeanNamesWithType.entrySet()) { |
|
|
|
if (isTypeMatch(candidate, dependencyType) && !candidate.equals(beanName)) { |
|
|
|
String candidateName = candidate.getKey(); |
|
|
|
|
|
|
|
Class<?> candidateType = candidate.getValue(); |
|
|
|
|
|
|
|
if (!candidateName.equals(beanName) && (candidateType != Void.class ? |
|
|
|
|
|
|
|
dependencyType.isAssignableFrom(candidateType) : // cached singleton class for primary bean
|
|
|
|
|
|
|
|
isTypeMatch(candidateName, dependencyType))) { // not instantiated yet or not a singleton
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|