spring官网讲解的循环依赖问题

查看spring官网,它是这么介绍循环依赖的问题的

重点内容有:

在使用构造函数注入实例时,spring ioc会抛出bean在创建的错误

我们可以写一个例子来证明:

serviceA/B,  都使用了构造方法将对方注入自己的类中

                  

clientConstructor:

就会形成一种无穷尽的依赖关系,在()里需要一直写service对象。所以说使用构造方法是没办法解决循环依赖的问题的,spring官网推荐我们使用setter方法,下面我们再来尝试一下:

serviceA/B

          

clientConstructor中,我们其实是使用了无参构造方法

运行结果:

结论:我们AB循环依赖问题只要A的注入方式是setter且是singleton,就不会有循环依赖问题
 

 

接下来我们再结合spring 容器IOC进行测试,单例和多例的区别

在配置文件中,我们需要定义bean的ID和参数

我们将默认的scope为singleton改成了prototype之后,会报这么一个错误


 

所以说spring的循环依赖只是在解决单例的问题,不解决多例,为什么呢?

 

spring是如何解决循环依赖的问题呢?运用的是哪三级缓存呢?

首先我们需要记住一个class类,这个类是源码查看三级缓存的类:defaultSingletonBeanRegistry

由图可知:解决循环依赖的三个缓存有:singletonObjects、singletonFactories、earlySingletonObjects ,仔细观察可以发现三个都是Map,value值分别是Object 、 ObjectFactories

其中这里注解一下三级缓存的概念:


singletonObjects :一级缓存,也叫做单例池,存放已经经历了完整生命周期的bean对象--------放成品的


earlySingletonObjects: 二级缓存,存放早期暴露出来的bean对象,bean的生命周期未结束(属性还未填充完整)----------放半成品的


singletonFactories :三级缓存,存放可以生成Bean的工厂,准备来构建对象的------准备生产的

 

一级和二级的Map的value都是Object类型,只有三级缓存是ObjectFactory类型

 

 

 

实例化和初始化:

实例化:内存中申请一块内存,通俗的话来说,就是先买了一套刚刚建好的房子,里面什么都没有,也就是毛坯房。

初始化:初始属性填充。通俗的话来说,给房子装修,将家居搬进去

 

循环依赖的三个Map和四个方法

先从一级缓存的singletonObjects里面拿对象,发现拿不到,就开始准备创建doCreateBean,创建好了之后就准备属性填充populateBean,属性填充好了之后,就将对象从缓存中取出来放在一级缓存,singletonObjects中

spring容器创建bean的大致流程是


1、A创建过程中需要B,于是A将自己放在三级缓存singletonFactory中,就去实例化B了
2、B 实例化的过程中发现自己需要A,于是从一级缓存singletonObjects中去查看,没有再去查看earlySingletonObjects,还是没有,再查三级缓存,发现A在三级缓存中,于是把三级缓存中的A就放到二级缓存中,并删除三级缓存里存储的A
3、得到二级缓存里的A之后,B顺利初始化完成,将自己放到一级缓存里面(此时的A还是在二级缓存中,依然是创建中的状态)然后回来接着创建A,此时A可以在一级缓存中直接拿到B,然后完成创建,并将A自己放到一级缓存里面

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你在狗叫什么、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值