spring中两个bean之间使用@Autowire相互依赖,仍然报循环依赖问题的原因

问题描述

spring明明使用三级缓存解决循环依赖,那为什么业务代码两个service间使用autowire注解互相依赖,还会因循环依赖问题而报错?

演示

在这里插入图片描述
在这里插入图片描述

启动spring容器时,就会因循环依赖问题而启动失败在这里插入图片描述

问题分析:

spring明明是使用三级缓存解决了循环依赖问题,除了这两种情况无法解决外:①使用构造函数注入对象;②bean的作用域是原型(prototype)
那已经避开这两种情况,使用@Autowire相互依赖,仍然会报依赖循环问题?

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

对象的创建过程:
①实例化(createBeanInstance);②属性注入(populateBean);③初始化过程(initializeBean)。
循环依赖时发生在属性注入阶段;

而spring是这样解决的:
1、先实例化userService,并对该bean创建对象工厂factoryBean,并将其getObjct逻辑作为lambda表达式放入第三级缓存(singletonFactories);
2、userService要注入orderService,就先从第一级缓存找orderService,找不到就判断是否在创建中,此时就开始创建orderService,也是步骤1的操作,此时orderService要注入userService,判断它在创建中,就到二级缓存中找 ,找不到就到三级缓存中找;
3、因为步骤1,所以可以从三级缓存中找到,就执行getObject逻辑生成userService对象(此时仍然未初始化完毕),或判断有transactional注解或自定义aop,就会生成userService的代理对象,并放入二级缓存中,并删除三级缓存,然后orderService还要完成接下来的初始化阶段,此时orderService已经创建完毕,可以放入一级缓存;
4、因步骤3,userService也可以注入orderService,再完成初始化即可;

spring就是这样完美的解决了依赖循环;

找到问题原因

于是翻看源码发现,在执行BeanFactoryPostProcessor的阶段是可以关闭循环依赖的开关,于是就思考是不是spring默认关闭了循环依赖的开关
果然,查看官网发现
在这里插入图片描述
在2.6.0版本后,就默认关闭循环依赖的开关。

解决问题

开启循环依赖开关
在这里插入图片描述

思考关闭循环依赖开关的原因

其实循环依赖说到底是因为编写代码不规范导致的,为了约束代码规范,于是spring官方默认关闭了开关,但仍然保留开启循环依赖;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值