单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取,当然这里只是尝试加载,首先尝试从缓存中加载,然后再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上一个bean,则直接使用ObjectFactory。
protected Object getSingleton(String beanName,boolean allowEarlyReference)
// 检查缓存中是否存在实例
// 如果为空,则锁定全局变量并进行处理
// 如果此bean正在加载则不处理
// 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
// 调用预先设定的getObject方法
// 记录在缓存中,earlySingletonObjects和singletonFactories互斥
}
a.singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean Name->bean instance。
b.singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,bean name-> ObjectFactory。
c.earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects不同之处是,当一个单例bean被放到这里,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用的。
d.registeredSingleton:用于保存当前所用已注册的bean。