提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


文章目录

  • 循环依赖
  • N个Bean互相引用对方,最终形成闭环。
  • 前提保证:
  • 创造的所有对象都是==单例对象==.
  • 循环依赖的问题:
  • 如果是通过==构造器==的方式, 那么没办法解决.
  • 如果是通过==set==的方式, 那么可以使用==三级缓存==解决此问题
  • 案例:
  • ==ref元素==是将目标Bean定义的==实例==注入到属性或构造函数中
  • 1.通过==构造函数==进行对象的创建
  • 2.通过==set方式==进行对象的创建
  • bean的生命周期
  • 三级缓存 ==DefaultSingletonBeanRegistry==
  • DefaultSingletonBeanRegistry类:
  • 一级缓存: singletonObjects
  • 用于存放==完全初始化好的 bean对象==,从该缓存中取出的 bean 可以直接使用
  • 二级缓存: earlySingletonObjects
  • 提前曝光的单例对象的cache,存放==完成实例化但未初始化 bean 对象==(尚未填充属性),用于解决循环依赖
  • 三级缓存:singletonFactories:
  • 单例对象工厂的cache,存放 ==bean 工厂对象(lambda表达式)==,用于解决循环依赖
  • 三级缓存读取顺序:
  • Spring解决循环依赖的诀窍:就在于==singletonFactories==这个三级缓存。
  • private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  • 1.==singletonFactories这个三级缓存这个Cache里面都是ObjectFactory实例,它是解决问题的关键==
  • 2.==经过ObjectFactory.getObject() 获取一个半成品对象==,此时放进了二级缓存earlySingletonObjects内。这个时候==对象已经实例化了但未初始化==,(尚未填充属性)虽然还不完美,但是==对象的引用==已经可以被其它引用了。
  • debug 源码
  • **ClassPathXmlApplicationContext**
  • AbstractApplicationContext
  • DefaultListableBeanFactory
  • DefaultListableBeanFactory 继承 DefaultSingletonBeanRegistry
  • ==此过程中先创建A对象==
  • AbstractBeanFactory
  • 进入 ==getSingleton(beanName) 方法==;
  • 父类DefaultSingletonBeanRegistry的中方法 ![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143949_66ff8db5765a031119.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • DefaultSingletonBeanRegistry
  • ==一级缓存 : singletonObjects==
  • 一路返回 到AbstractBeanFactory
  • AbstractBeanFactory
  • 还是==DefaultSingletonBeanRegistry==中 getSingleton方法 只是形参不一样
  • getSingleton方法参数之一是==ObjectFactory实例==
  • 实例就必须重写抽象的getObject方法 ,spring是用lambda表达式的形式
  • lambda表达式![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143952_66ff8db89b8e957545.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • DefaultSingletonBeanRegistry
  • 此时一级缓存里还没有a对象
  • AbstractAutowireCapableBeanFactory
  • ==createBeanInstance(beanName, mbd, args)==; 方法
  • 这个方法里面是利用反射创建好 ==空属性 或者默认属性的a对象==
  • ==addSingletonFactory(String , ObjectFactory<?> ) {}==
  • DefaultSingletonBeanRegistry里面的方法
  • 如果一级缓存没有对象![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143956_66ff8dbcd9a9e20502.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 清空二级缓存![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143957_66ff8dbd3034e38345.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • set集合添加bean对象的名字![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143957_66ff8dbd5f69b5833.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 一组已注册的单例,按注册顺序包含bean名称的==set集合==![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04143957_66ff8dbd8acd714821.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • ==此时三级缓存里 放的是lambda表达式的实例==
  • 进入 ==populate()方法 做属性填充==
  • AbstractAutowireCapableBeanFactory
  • BeanDefinitionValueResolver
  • 因为a对象的属性b,是一个对象,
  • 所以此时要从beanFactory.getBean(String name)获取b对象
  • ==开始循环==
  • 开始循环 1
  • AbstractBeanFactory
  • 此时a,b两个对象都已实例化完成,但都还未初始化
  • 往三级缓存map 添加元素
  • 进入 populateBean(beanName, mbd, instanceWrapper);
  • 给b对象填充属性
  • 此时a,b对象都已实例化,但都未初始化 ==属于创建过程中==
  • 显然此时二级缓存是获取不到a的,所以singletonObject == null
  • 此时三级缓存map存放着 {key = a ,value= lambda表达式的实例 }![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04144011_66ff8dcb10ea162619.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 获取ObjectFactory<?> 类型的 lambda表达式实例,然后调用getObject()方法
  • ==往二级缓存map添加元素== ,
  • (key =beanName ,value =a对象 (此时a对象只实例化 未初始化)}
  • ==从三级缓存map里清除, key=a 的元素== ,
  • ==三级缓存读取的顺序==
  • 此时
  • 一路返回
  • 一路返回
  • 一路返回
  • ==往一级缓存添加 实例完且初始化完的 完整状态的b对象==
  • 此时
  • ==此时b对象是完整转态的b对象,(实例化且初始化完成)==![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04144017_66ff8dd1c6cca79377.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 一路返回
  • 一路返回![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04144019_66ff8dd355fc242149.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 一路返回
  • 一路返回
  • 一路返回
  • 此时 ![在这里插入图片描述](https://s2.51cto.com/images/blog/202410/04144021_66ff8dd5dc33943052.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
  • 一路返回
  • 开始循环 2
  • ==此时 a,b 对象 都已创建成功==
  • 总结:
  • 解决循环依赖的关键
  • 1.==singletonFactories这个三级缓存这个Cache里面都是ObjectFactory实例,它是解决问题的关键==
  • 2.==经过ObjectFactory.getObject() 获取一个半成品对象==,此时放进了二级缓存earlySingletonObjects内。这个时候==对象已经实例化了但未初始化==,(尚未填充属性)虽然还不完美,但是==对象的引用==已经可以被其它引用了。



循环依赖

N个Bean互相引用对方,最终形成闭环。

spring三级缓存中完整流程_缓存

spring三级缓存中完整流程_spring_02

前提保证:

创造的所有对象都是单例对象.

循环依赖的问题:

如果是通过构造器的方式, 那么没办法解决.
如果是通过set的方式, 那么可以使用三级缓存解决此问题

案例:

class A

package springdemo.cy.bean;

public class A {

    private  B b;

    public A(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

class B

package springdemo.cy.bean;

public class B {

    private A a;

    public B(A a) {
        this.a =a;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public  void  show(){
        System.out.println("B.....show");
    }
}

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="a" class="springdemo.cy.bean.A">
     <property name="b" ref="b" ></property>
    </bean>


    <bean id="b" class="springdemo.cy.bean.B">
         <property name="a"  ref="a"></property>
    </bean>

</beans>
ref元素是将目标Bean定义的实例注入到属性或构造函数中

1.通过构造函数进行对象的创建

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import springdemo.cy.bean.B;

public class test {

    public static void main(String[] args) throws Exception {

    ApplicationContext context = new ClassPathXmlApplicationContext("test.xml");

        B bean = context.getBean(B.class);

        bean.show();
        System.out.println(bean);

    }

}

spring三级缓存中完整流程_spring_03

2.通过set方式进行对象的创建

spring三级缓存中完整流程_spring三级缓存中完整流程_04


spring三级缓存中完整流程_spring_05

bean的生命周期

spring三级缓存中完整流程_三级缓存_06

spring三级缓存中完整流程_spring_07

spring三级缓存中完整流程_缓存_08


spring三级缓存中完整流程_缓存_09

spring三级缓存中完整流程_三级缓存_10

三级缓存 DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry类:

spring三级缓存中完整流程_spring_11

spring三级缓存中完整流程_三级缓存_12

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	...
	// 从上至下 分表代表这“三级缓存”
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一级缓存
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存
	...
	
	/** Names of beans that are currently in creation. */
	// 这个缓存也十分重要:它表示bean创建过程中都会在里面呆着~
	// 它在Bean开始创建时放值,创建完成时会将其移出~
	private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** Names of beans that have already been created at least once. */
	// 当这个Bean被创建完成后,会标记为这个 注意:这里是set集合 不会重复
	// 至少被创建了一次的  都会放进这里~~~~
	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
}

一级缓存: singletonObjects

用于存放完全初始化好的 bean对象,从该缓存中取出的 bean 可以直接使用

二级缓存: earlySingletonObjects

提前曝光的单例对象的cache,存放完成实例化但未初始化 bean 对象(尚未填充属性),用于解决循环依赖

三级缓存:singletonFactories:

单例对象工厂的cache,存放 bean 工厂对象(lambda表达式),用于解决循环依赖

三级缓存读取顺序:

/**
	 * 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
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//从一级缓存获取
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果一级缓存中没有,并且已标记这个bean正在被定义
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				//从二级缓存获取bean
				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;
	}

spring三级缓存中完整流程_三级缓存_13

  1. 先从一级缓存singletonObjects中去获取。(如果获取到就直接return)
  2. 如果获取不到或者对象正在创建中(isSingletonCurrentlyInCreation()),那就再从二级缓存earlySingletonObjects中获取。(如果获取到就直接return)
  3. 如果还是获取不到,且允许singletonFactories(allowEarlyReference=true)通过getObject()获取。就从三级缓存singletonFactory.getObject()获取。获取不到 return null
  4. 如果获取到了就从singletonFactories中移除,并且放进二级缓存earlySingletonObjects。其实也就是从三级缓存移动(是剪切、不是复制哦~)到了二级缓存.然后再返回获取到的这个对象

Spring解决循环依赖的诀窍:就在于singletonFactories这个三级缓存。

前提:

  • 加入singletonFactories三级缓存的前提是执行了构造器,所以构造器的循环依赖没法解决
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

spring三级缓存中完整流程_spring_14

1.singletonFactories这个三级缓存这个Cache里面都是ObjectFactory实例,它是解决问题的关键
2.经过ObjectFactory.getObject() 获取一个半成品对象,此时放进了二级缓存earlySingletonObjects内。这个时候对象已经实例化了但未初始化,(尚未填充属性)虽然还不完美,但是对象的引用已经可以被其它引用了。

debug 源码

spring三级缓存中完整流程_缓存_15

ClassPathXmlApplicationContext

spring三级缓存中完整流程_spring_16

AbstractApplicationContext

spring三级缓存中完整流程_spring三级缓存中完整流程_17

spring三级缓存中完整流程_spring三级缓存中完整流程_18


spring三级缓存中完整流程_java_19


spring三级缓存中完整流程_三级缓存_20

DefaultListableBeanFactory

spring三级缓存中完整流程_缓存_21

DefaultListableBeanFactory 继承 DefaultSingletonBeanRegistry

spring三级缓存中完整流程_java_22


spring三级缓存中完整流程_缓存_23

spring三级缓存中完整流程_spring_24

此过程中先创建A对象

spring三级缓存中完整流程_spring三级缓存中完整流程_25


spring三级缓存中完整流程_三级缓存_26


spring三级缓存中完整流程_三级缓存_27

AbstractBeanFactory

spring三级缓存中完整流程_spring三级缓存中完整流程_28

spring三级缓存中完整流程_缓存_29


spring三级缓存中完整流程_spring三级缓存中完整流程_30

进入 getSingleton(beanName) 方法;

父类DefaultSingletonBeanRegistry的中方法

spring三级缓存中完整流程_java_31

DefaultSingletonBeanRegistry

spring三级缓存中完整流程_缓存_32

spring三级缓存中完整流程_缓存_33

一级缓存 : singletonObjects

spring三级缓存中完整流程_spring三级缓存中完整流程_34

spring三级缓存中完整流程_spring三级缓存中完整流程_35


spring三级缓存中完整流程_spring三级缓存中完整流程_36

一路返回 到AbstractBeanFactory

AbstractBeanFactory

spring三级缓存中完整流程_spring_37


spring三级缓存中完整流程_缓存_38

还是DefaultSingletonBeanRegistry中 getSingleton方法 只是形参不一样

spring三级缓存中完整流程_三级缓存_39

getSingleton方法参数之一是ObjectFactory实例

实例就必须重写抽象的getObject方法 ,spring是用lambda表达式的形式

spring三级缓存中完整流程_缓存_40

lambda表达式

spring三级缓存中完整流程_spring三级缓存中完整流程_41

spring三级缓存中完整流程_spring_42

DefaultSingletonBeanRegistry

spring三级缓存中完整流程_java_43

此时一级缓存里还没有a对象

spring三级缓存中完整流程_java_44


spring三级缓存中完整流程_spring三级缓存中完整流程_45

AbstractAutowireCapableBeanFactory

spring三级缓存中完整流程_spring三级缓存中完整流程_46


spring三级缓存中完整流程_java_47


spring三级缓存中完整流程_java_48


spring三级缓存中完整流程_缓存_49

createBeanInstance(beanName, mbd, args); 方法

这个方法里面是利用反射创建好 空属性 或者默认属性的a对象

spring三级缓存中完整流程_java_50


spring三级缓存中完整流程_三级缓存_51


spring三级缓存中完整流程_三级缓存_52


spring三级缓存中完整流程_spring三级缓存中完整流程_53


spring三级缓存中完整流程_spring_54

addSingletonFactory(String , ObjectFactory<?> ) {}

DefaultSingletonBeanRegistry里面的方法

spring三级缓存中完整流程_三级缓存_55

如果一级缓存没有对象

spring三级缓存中完整流程_spring三级缓存中完整流程_56

清空二级缓存

spring三级缓存中完整流程_spring三级缓存中完整流程_57

set集合添加bean对象的名字

spring三级缓存中完整流程_spring三级缓存中完整流程_58

一组已注册的单例,按注册顺序包含bean名称的set集合

spring三级缓存中完整流程_spring_59

此时三级缓存里 放的是lambda表达式的实例

spring三级缓存中完整流程_三级缓存_60

spring三级缓存中完整流程_spring_61


spring三级缓存中完整流程_spring三级缓存中完整流程_62

进入 populate()方法 做属性填充

AbstractAutowireCapableBeanFactory

spring三级缓存中完整流程_spring_63


spring三级缓存中完整流程_spring_64


spring三级缓存中完整流程_spring三级缓存中完整流程_65


spring三级缓存中完整流程_三级缓存_66


spring三级缓存中完整流程_spring三级缓存中完整流程_67


spring三级缓存中完整流程_spring三级缓存中完整流程_68


spring三级缓存中完整流程_spring三级缓存中完整流程_69


spring三级缓存中完整流程_三级缓存_70

BeanDefinitionValueResolver

spring三级缓存中完整流程_缓存_71


spring三级缓存中完整流程_三级缓存_72


spring三级缓存中完整流程_spring三级缓存中完整流程_73


spring三级缓存中完整流程_三级缓存_74


spring三级缓存中完整流程_java_75


spring三级缓存中完整流程_缓存_76

因为a对象的属性b,是一个对象,

所以此时要从beanFactory.getBean(String name)获取b对象

开始循环

开始循环 1

AbstractBeanFactory

spring三级缓存中完整流程_spring_77


spring三级缓存中完整流程_spring_78


spring三级缓存中完整流程_java_79


spring三级缓存中完整流程_三级缓存_80


spring三级缓存中完整流程_java_81


spring三级缓存中完整流程_java_82


spring三级缓存中完整流程_spring_83


spring三级缓存中完整流程_spring三级缓存中完整流程_84


spring三级缓存中完整流程_spring_85


spring三级缓存中完整流程_spring_86


spring三级缓存中完整流程_java_87

此时a,b两个对象都已实例化完成,但都还未初始化

spring三级缓存中完整流程_spring三级缓存中完整流程_88

spring三级缓存中完整流程_java_89


spring三级缓存中完整流程_三级缓存_90


spring三级缓存中完整流程_spring三级缓存中完整流程_91

往三级缓存map 添加元素

spring三级缓存中完整流程_spring三级缓存中完整流程_92


spring三级缓存中完整流程_三级缓存_93

进入 populateBean(beanName, mbd, instanceWrapper);

给b对象填充属性

spring三级缓存中完整流程_缓存_94


spring三级缓存中完整流程_缓存_95


spring三级缓存中完整流程_spring三级缓存中完整流程_96


spring三级缓存中完整流程_spring_97


spring三级缓存中完整流程_三级缓存_98


spring三级缓存中完整流程_java_99


spring三级缓存中完整流程_缓存_100


spring三级缓存中完整流程_三级缓存_101

此时a,b对象都已实例化,但都未初始化 属于创建过程中

spring三级缓存中完整流程_三级缓存_102

spring三级缓存中完整流程_三级缓存_103


spring三级缓存中完整流程_spring三级缓存中完整流程_104

显然此时二级缓存是获取不到a的,所以singletonObject == null

spring三级缓存中完整流程_缓存_105


spring三级缓存中完整流程_spring三级缓存中完整流程_106

此时三级缓存map存放着 {key = a ,value= lambda表达式的实例 }

spring三级缓存中完整流程_spring_107

获取ObjectFactory<?> 类型的 lambda表达式实例,然后调用getObject()方法

spring三级缓存中完整流程_spring_108


spring三级缓存中完整流程_spring_109


spring三级缓存中完整流程_缓存_110


spring三级缓存中完整流程_三级缓存_111

往二级缓存map添加元素 ,
(key =beanName ,value =a对象 (此时a对象只实例化 未初始化)}

spring三级缓存中完整流程_java_112

spring三级缓存中完整流程_spring三级缓存中完整流程_113

从三级缓存map里清除, key=a 的元素 ,

三级缓存读取的顺序

spring三级缓存中完整流程_三级缓存_13

  1. 先从一级缓存singletonObjects中去获取。(如果获取到就直接return)
  2. 如果获取不到或者对象正在创建中(isSingletonCurrentlyInCreation()),那就再从二级缓存earlySingletonObjects中获取。(如果获取到就直接return)
  3. 如果还是获取不到,且允许singletonFactories(allowEarlyReference=true)通过getObject()获取。就从三级缓存singletonFactory.getObject()获取。获取不到
    return null
  4. 如果获取到了就从singletonFactories中移除,并且放进二级缓存earlySingletonObjects。其实也就是从三级缓存移动(是剪切、不是复制哦~)到了二级缓存.然后再返回获取到的这个对象

此时

  • 一级缓存
  • 二级缓存
  • 三级缓存

spring三级缓存中完整流程_缓存_115

一路返回

spring三级缓存中完整流程_spring_116

一路返回

spring三级缓存中完整流程_三级缓存_117

一路返回

spring三级缓存中完整流程_三级缓存_118


spring三级缓存中完整流程_spring_119


spring三级缓存中完整流程_spring三级缓存中完整流程_120


spring三级缓存中完整流程_缓存_121


spring三级缓存中完整流程_三级缓存_122

往一级缓存添加 实例完且初始化完的 完整状态的b对象

spring三级缓存中完整流程_spring三级缓存中完整流程_123


spring三级缓存中完整流程_spring_124


spring三级缓存中完整流程_spring三级缓存中完整流程_125


spring三级缓存中完整流程_spring三级缓存中完整流程_126


spring三级缓存中完整流程_三级缓存_127

此时

此时b对象是完整转态的b对象,(实例化且初始化完成)

spring三级缓存中完整流程_java_128

spring三级缓存中完整流程_三级缓存_129


spring三级缓存中完整流程_spring三级缓存中完整流程_130


spring三级缓存中完整流程_spring三级缓存中完整流程_131

一路返回

spring三级缓存中完整流程_缓存_132


spring三级缓存中完整流程_spring_133

一路返回

spring三级缓存中完整流程_java_134

一路返回

spring三级缓存中完整流程_java_135


spring三级缓存中完整流程_java_136

一路返回

spring三级缓存中完整流程_缓存_137

一路返回

spring三级缓存中完整流程_三级缓存_138


spring三级缓存中完整流程_三级缓存_139


spring三级缓存中完整流程_java_140


spring三级缓存中完整流程_java_141

此时

spring三级缓存中完整流程_缓存_142

spring三级缓存中完整流程_spring_143


spring三级缓存中完整流程_spring_144


spring三级缓存中完整流程_spring三级缓存中完整流程_145

spring三级缓存中完整流程_缓存_146

一路返回

spring三级缓存中完整流程_spring_147


spring三级缓存中完整流程_缓存_148


spring三级缓存中完整流程_spring三级缓存中完整流程_149

开始循环 2

spring三级缓存中完整流程_java_150


spring三级缓存中完整流程_java_151


spring三级缓存中完整流程_缓存_152


spring三级缓存中完整流程_三级缓存_153


spring三级缓存中完整流程_spring_154


spring三级缓存中完整流程_java_155

此时 a,b 对象 都已创建成功

spring三级缓存中完整流程_spring三级缓存中完整流程_156

总结:

spring三级缓存中完整流程_spring_157

spring三级缓存中完整流程_缓存_158


spring三级缓存中完整流程_三级缓存_159

spring三级缓存中完整流程_spring三级缓存中完整流程_160


spring三级缓存中完整流程_缓存_161

解决循环依赖的关键

1.singletonFactories这个三级缓存这个Cache里面都是ObjectFactory实例,它是解决问题的关键
2.经过ObjectFactory.getObject() 获取一个半成品对象,此时放进了二级缓存earlySingletonObjects内。这个时候对象已经实例化了但未初始化,(尚未填充属性)虽然还不完美,但是对象的引用已经可以被其它引用了。

spring三级缓存中完整流程_三级缓存_162