5.2缓存中获取单例bean
DefaultSingletonBeanRegistry public Object getSingleton(String beanName) { //参数true设置标识允许早期依赖(提前引用) return getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock //检查缓存中是否存在实例 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //缓存中没有实例但是又在创建中,那么可能是循环依赖,解决循环依赖的方式是 //Spring创建bean的原则是不等bean创建完成就会创建bean的ObjectFactory提早曝光 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { //如果为空,则锁定全局变量并进行处理 synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的 //ObjectFactory初始化策略存储在singletonFactories 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; }
- singletonObjects:用于保存BeanName和创建bean实例直接的关系,bean name--> bean instance.
- singletonFactories:用于保存BeanName和创建bean的工厂之间的关系,beanname-->ObjectFactory.当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
- earlySingletonObjects:也是保存BeanName和创建bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这里面后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环应用的。
- registeredSingletons:用来保存当前所有已注册的bean。
大致逻辑:
首先尝试从singleObjects里面获取实例,如果获取不到,尝试从earlySingletonObjects中获取,如果还获取不到,再尝试从singletonFactories中获取beanName对应的ObjectFactory,调用ObjectFactory的getObject来创建bean,并放到earlySingleton-Objects,singletonFactories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测的时候使用,也就是在allowEarlyReference为true的情况下才会使用。

浙公网安备 33010602011771号