关于java:Spring-水滴石穿五-工厂实现之单例注册-DefaultSingletonBeanRegistry

15次阅读

共计 2779 个字符,预计需要花费 7 分钟才能阅读完成。

概述

这个 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);
        }
    }

上面是真正做事件的办法,它会在一级缓存外面增加数据,其余缓存通通删除

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 创立实现就会陷入死循环中。

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;
    }
正文完
 0