200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > [spring] 源码简析 如何解决循环依赖?

[spring] 源码简析 如何解决循环依赖?

时间:2023-12-15 13:25:38

相关推荐

[spring] 源码简析 如何解决循环依赖?

spring是创建实例的时候,是如何解决循环依赖的呢?

先来看一下isSingleton的实例getBean的整个流程:

步骤一

sharedInstance = getSingleton(name)

来获取缓存的单例实例

(来源两处,参见图中同色系框框,

一、单例创建完了会缓存一份singletonObjects;

二、创建过程中会缓存一份singletonFactories,创建完了删除)

如果能够获取得到,则直接返回bean

如果获取不到,则走getSingleton来实例化单例(参见步骤二)

步骤二

getSingleton(name)

将自身加singletonsCurrentlyInCreation(正在创建的单例容器)中

执行createBean方法(步骤三)

将自身从singletonsCurrentlyInCreation(正在创建的单例容器)中移除

创建的单例实例加入到单例缓存singletonObjects中

步骤三

createBean方法

通过构造函数创建实例

如果是单例 & 允许循环依赖&

该bean在singletonsCurrentlyInCreation(正在创建的单例容器)中,则将上述创建的实例缓存到singletonFactories

populatBean依赖注入属性,如果属性是beanName,则调用getBean回到开头

假设spring没有去解决循环依赖的问题,假设新建如下两个类:

1@Component2public class A {34 @Autowired5 private B b;678 public A() {9 System.out.println("A Constructor");10 }1112 @Override13 public String toString() {14 return "A{}";15 }16}1@Component2public class B {34 @Autowired5 private A a;678 public B() {9 System.out.println("B Constructor");10 }111213 @Override14 public String toString() {15 return "B{}";16 }17}

那么,在创建A的单例的过程中,需要依赖注入B,转而去创建B,B的创建过程中又要依赖注入A,此时A在beanFactory中不存在,转而又去创建A,这样会形成一种死循环。

问题的解决办法,就是要在创建过程中,有一条分支路线能够终止创建过程并且返回对象。

spring是怎么解决循环依赖的呢?

在创建一个单例的过程中,一旦通过构造函数创建了一个实例,就将中间过程的实例对象暂时缓存起来。

--> 创建A①

--> 执行到步骤三的第2步时,会将刚刚通过构造函数新建的实例缓存起来

--> 执行步骤三的第3步,依赖注入B,去创建B

--> B又依赖注入A,创建A

--> 步骤一中能直接从缓存singletonFactories获取到对象 return a

--> invoke b.setA(a)

--> return B

--> invoke a.setB(b)

--> return A

以上

更多源码分析,关注公众号???

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。