Spring源码分析---缓存中获取单例bean

单例在Spring中的同一个容器中只会被创建一次,后续在获取bean,可以直接从单例缓存中获取;首先从缓存中加载,然后在尝试从singletonFactories中加载。
由于在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提曝光加入到缓存中,一旦下一个bean创建时需要上一个bean,则直接使用ObjectFactory。

public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //检查缓存中是否存在实例
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null ) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //调用预先设定的getObject方法
                        singletonObject = singletonFactory.getObject();
                        //记录在缓存中,earlySingletonObjects和singletonFactories互斥
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

这方法首先尝试从singletonObjects里面获取实例,如果获取不到在从earlySingletonObjects里面获取,如果在获取不到,在尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingletonObjects里面去,并且从singletonFactories里面remove掉这个ObjectFactory。

singletonObjects

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

singletonFactories

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

earlySingletonObjects

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

registeredSingletons

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

参考:《Spring源码深度解析》

你可能感兴趣的:(Spring源码分析---缓存中获取单例bean)