Spring 水滴石穿(五) 工厂实现之单例注册 DefaultSingletonBeanRegistry

概述

这个class是个比较关键的类,它也是后面的完成工厂所继承的顶级class,主要就是实现别名注册接口和单例注册接口,从而提供这些服务。缓存

属性

//抑制异常最多100个
    private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;

    //一级缓存,缓存beanName和bean实例
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    //二级缓存,缓存beanName和单例工厂
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    //三级缓存,缓存beanName和提早暴露的bean实例
    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));

    //建立检测时须要排除的bean的名字集合
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    //已抑制的异常的集合
    @Nullable
    private Set<Exception> suppressedExceptions;

    //标识是否当前处于销毁单例过程
    private boolean singletonsCurrentlyInDestruction = false;

    //可销毁的bean实例
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

    //bean和它包含的bean之间的map
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

    //bean和依赖它的bean之间的map
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

    //bean和它依赖的bean之间的map,注意与上面的区别
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

方法

registerSingleton

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        synchronized (this.singletonObjects) {
            Object oldObject = this.singletonObjects.get(beanName);
            if (oldObject != null) {
                throw new IllegalStateException("Could not register object [" + singletonObject +
                        "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
            }
            addSingleton(beanName, singletonObject);
        }
    }

下面是真正作事情的方法,它会在一级缓存里面添加数据,其余缓存通通删除this

protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

这里为什么要用俩个synchronized关键字?最外层的保留不就好了?设计

getSingleton

返回一个单例,注意这里有个参数是否容许提早暴露一个实例化完成,但初始化未完成的bean,之因此要这样设计是为了解决循环引用问题,这个问题很简单,就是beanA依赖beanB,beanB依赖beanA若是每一个都去等待另外一个bean建立完成就会陷入死循环中。code

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
相关文章
相关标签/搜索