SingletonBeanRegistry 支持单例的注册
void registerSingleton(String var1, Object var2);
@Nullable
Object getSingleton(String var1);
boolean containsSingleton(String var1);
String[] getSingletonNames();
int getSingletonCount();
Object getSingletonMutex();
具体实现类DefaultSingtonBeanRegistry
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {}
//单例Object(可用)
private final Map singletonObjects = new ConcurrentHashMap(256);
//单例的Factory
private final Map> singletonFactories = new HashMap(16);
//解决依赖问题(提前曝光,class 只有一个空壳,属性还有实例化)
private final Map earlySingletonObjects = new HashMap(16);
//已经注册的单例
private final Set registeredSingletons = new LinkedHashSet(256);
// 单例是否已经在创建之中
private final Set singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
// 不可以配置的class
private final Set inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap(16));
//支持异常
@Nullable
private Set suppressedExceptions;
private boolean singletonsCurrentlyInDestruction = false;
//已回收的class
private final Map disposableBeans = new LinkedHashMap();
//一个class 所依赖的class
private final Map> containedBeanMap = new ConcurrentHashMap(16);
//依赖 原始的class
private final Map> dependentBeanMap = new ConcurrentHashMap(64);
一个class 哪些class 需要依赖他
private final Map> dependenciesForBeanMap = new ConcurrentHashMap(64);
参考
(
同时这边也有inCreationCheckExclusions和singletonsCurrentlyInCreation进行锁控制的概念.
singletonsCurrentlyInCreation缓存bean正在被初始化,这样就不能再发起初始化;
inCreationCheckExclusions 直接缓存当前不能加载的bean
这部分看个例子就,清晰了,初始化前需要先使用beforeSingletonCreation判断
这边inCreationCheckExclusions不包含beanName才会去判断singletonsCurrentlyInCreation
1 protected void beforeSingletonCreation(String beanName) {
2 if (!this.inCreationCheckExclusions.containsKey(beanName) &&
3 this.singletonsCurrentlyInCreation.put(beanName, Boolean.TRUE) != null) {
4 throw new BeanCurrentlyInCreationException(beanName);
5 }
6 }
)
需要有点说明
singletonFactories 曝光在 earlySingletonObjects 之前,通过 一下代码可得出结论
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
添加 依赖
public void registerContainedBean(String containedBeanName, String containingBeanName) { Map var3 = this.containedBeanMap; synchronized(this.containedBeanMap) { SetcontainedBeans = (Set)this.containedBeanMap.computeIfAbsent(containingBeanName, (k) -> { return new LinkedHashSet(8); }); if (!containedBeans.add(containedBeanName)) { return; } } this.registerDependentBean(containedBeanName, containingBeanName); } public void registerContainedBean(String beanName, String dependentBeanName) { String canonicalName = this.canonicalName(beanName); Map var4 = this.dependentBeanMap; Set dependenciesForBean; synchronized(this.dependentBeanMap) { dependenciesForBean = (Set)this.dependentBeanMap.computeIfAbsent(canonicalName, (k) -> { return new LinkedHashSet(8); }); if (!dependenciesForBean.add(dependentBeanName)) { return; } } var4 = this.dependenciesForBeanMap; synchronized(this.dependenciesForBeanMap) { dependenciesForBean = (Set)this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, (k) -> { return new LinkedHashSet(8); }); dependenciesForBean.add(canonicalName); } }
containedBeanMap 外部bean与被包含在外部bean的所有内部bean集合包含关系的缓存 (我包含bean,他的依赖关系) dependentBeanMap(指定的bean与目前已经注册的依赖这个指定的bean的所有bean的依赖关系的缓存(依赖我的)) dependenciesForBeanMap(指定bean与目前已经注册的创建这个bean所需依赖的所有bean的依赖关系的缓存(我依赖的 ))
依赖
参考
判断是否依赖,和 SimpleAliasRegistry,有一个判断链依赖的方法 A依赖B B依赖C
private boolean isDependent(String beanName, String dependentBeanName, @Nullable SetalreadySeen) { if (alreadySeen != null && ((Set)alreadySeen).contains(beanName)) { return false; } else { String canonicalName = this.canonicalName(beanName); Set dependentBeans = (Set)this.dependentBeanMap.get(canonicalName); if (dependentBeans == null) { return false; } else if (dependentBeans.contains(dependentBeanName)) { return true; } else { Iterator var6 = dependentBeans.iterator(); String transitiveDependency; do { if (!var6.hasNext()) { return false; } transitiveDependency = (String)var6.next(); if (alreadySeen == null) { alreadySeen = new HashSet(); } ((Set)alreadySeen).add(beanName); } while(!this.isDependent(transitiveDependency, dependentBeanName, (Set)alreadySeen)); return true; } } }
canonicalName 这里需要注意这个方法,
参考