美文网首页
Spring-IOC-尝试从缓存中加载单例

Spring-IOC-尝试从缓存中加载单例

作者: zhanglbjames | 来源:发表于2017-09-04 11:26 被阅读0次

单例在Spring的同一个容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。

  1. 先尝试从SingletonObjects缓存中加载实例;如果不成功则尝试从earlySingletonObjects中加载已经在创建完成之前提前暴露的单例Bean;如果失败了,则从singletonFactories中获取beanName对应的ObjectFactory,然后在调用ObjectFactory#getObject()方法创建对应的Bean,并放到earlySingletonObjects中,并从SingletonFactories中remove掉这个ObjectFactory。而对于后续的所有操作都只是为了循环依赖检测时候使用,也就是allowEarlyReference为true的情况下才使用。

  2. 为了解决循环依赖的问题,Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光加入到缓存中, 一旦下一个Bean创建时需要依赖上一个bean则直接使用ObjectFactory。

1. 从缓存中获取单例bean
beans.factory.support.DefaultSingletonBeanRegistry
    @Override
    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }
    /**
     * Return the (raw) singleton object registered under the given name.
     * <p>Checks already instantiated singletons and also allows for an early
     * reference to a currently created singleton (resolving a circular reference).
     * @param beanName the name of the bean to look for
     * @param allowEarlyReference whether early references should be created or not
     * @return the registered singleton object, or {@code null} if none found
     */
    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 != NULL_OBJECT ? singletonObject : null);
    }

简单解释一下用于存储bean的不同的map

  • singletonObjects

用于保存BeanName和创建bean实例之间的关系,bean name --> bean instance

  • singletonFactories

用于保存BeanName和创建bean的工厂之间的关系,bean name --> ObjectFactory

  • earlySingletonObjects

保运BeanName和创建bean实例之间的关系,与singletonObjects的不同在于,当一个单例bean被放到这里面后,name当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用。

  • registeredSingletons

用来保存当前所有已注册的单例bean

相关文章

网友评论

      本文标题:Spring-IOC-尝试从缓存中加载单例

      本文链接:https://www.haomeiwen.com/subject/utasjxtx.html