SingletonBeanRegistry 分析

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<String, Object> singletonObjects = new ConcurrentHashMap(256);
//单例的Factory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//解决依赖问题(提前曝光,class 只有一个空壳,属性还有实例化)
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
//已经注册的单例
private final Set<String> registeredSingletons = new LinkedHashSet(256);
// 单例是否已经在创建之中
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
// 不可以配置的class
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap(16));
//支持异常
@Nullable
private Set<Exception> suppressedExceptions;

private boolean singletonsCurrentlyInDestruction = false;
//已回收的class
private final Map<String, Object> disposableBeans = new LinkedHashMap();

//一个class 所依赖的class
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap(16);
//依赖 原始的class
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap(64);
一个class 哪些class 需要依赖他
private final Map<String, Set<String>> 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) {
        Set<String> containedBeans = (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 Set<String> alreadySeen) {
    if (alreadySeen != null && ((Set)alreadySeen).contains(beanName)) {
        return false;
    } else {
        String canonicalName = this.canonicalName(beanName);
        Set<String> 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 这里需要注意这个方法,

参考

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值