spring 循环依赖图解
2023-04-26 21:35:35 13 举报
Spring循环依赖是指在Spring容器中,两个或多个Bean之间形成了一个闭环的依赖关系。这种依赖关系会导致Spring容器无法正确地创建和初始化这些Bean。为了解决这个问题,Spring引入了三级缓存机制,即singletonObjects、earlySingletonObjects和singletonFactories。当Spring容器遇到循环依赖时,会将循环依赖的Bean提前暴露出来,让其他Bean先引用到这个Bean,然后再进行初始化。这样就避免了循环依赖导致的问题。 希望这能帮到你!如果你还有其他问题,请随时问我。
作者其他创作
大纲/内容
添加三级缓存
createBeanInstance(beanB...)
将 Bean A 添加到三级缓存
创建 Bean 对象
getSingleton(beanA....)
initializeBean(beanA ...)
最后完成beanA的初始化
populateBean(beanA ...)
getBean(beanA...)
initializeBean(beanB ...)
getSingleton(beanB,singletonFactory)
beanB获取beanA的早期引用
1. 由于第一步添加了缓存,所以这里不为空,2. 获取三级缓存中的 lambda 3. 将 A 从三级缓存移动到二级
doGetBean(beanB)
doGetBean(beanA)
getSingleton(beanA) ==null
doCreateBean(beanA....)
getBean(beanA)
注入属性时,发现依赖了B,获取 BeanB
尝试从各级缓存中的获取bean
注入属性时,发现依赖了A,获取 BeanA
getObjectForBeanInstance(...)
doCreateBean(beanB...)
getSingleton(beanB) ==null
返回bean的原始对象
属性注入
B 完成初始化以及实例化
1. 调用doGetBean()方法,想要获取beanA,于是调用getSingleton()方法从缓存中查找beanA2. 在getSingleton()方法中,从一级缓存中查找,没有,返回null3. doGetBean()方法中获取到的beanA为null,于是走对应的处理逻辑,调用getSingleton()的重载方法(参数为ObjectFactory的)4. 在getSingleton()方法中,先将beanA_name添加到一个集合中,用于标记该bean正在创建中。然后回调匿名内部类的creatBean()方法5. 进入AbstractAutowireCapableBeanFactory#doCreateBean(),先反射调用构造器创建出beanA的实例,然后判断是否为单例、是否允许提前暴露引用(对于单例一般为true)、是否正在创建中〈即是否在第四步的集合中)。判断为true则将beanA添加到【三级缓存】中6. 对beanA进行属性填充,此时检测到beanA依赖于beanB,于是开始查找beanB7. 调用doGetBean()方法,和上面beanA的过程一样,到缓存中查找beanB,没有则创建,然后给beanB填充属性8. 此时beanB依赖于beanA,调用getsingleton()获取beanA,依次从一级、二级、三级缓存中找,此时从三级缓存中获取到beanA的创建工厂,通过创建工厂获取到singletonObject,此时这个singletonObject指向的就是上面在doCreateBean()方法中实例化的beanA9. 这样beanB就获取到了beanA的依赖,于是beanB顺利完成实例化,并将beanA从三级缓存移动到二级缓存中10. 随后beanA继续他的属性填充工作,此时也获取到了beanB,beanA也随之完成了创建,回到getsingleton()方法中继续向下执行,将beanA从二级缓存移动到一级缓存中
先创建beanA
初始化bean
getSingleton(beanA,singletonFactory)
getBean(beanB)
populateBean(beanB ...)
开始创建 BeanA 实例
创建beanB
0 条评论
回复 删除
下一页