前言
大家好,今天的文章将帮助大家了解面试中经常被问到的 Spring 循环依赖。如果有错误的地方,可以在评论区讨论!
注:如果你只是一个CRUD砌砖工,则无需阅读,就算了。您只需滚动到最后,点赞、转发、保存即可一键保存。
1.什么是循环依赖?
多个bean相互依赖,形成一个闭环。例如:A依赖于B,B依赖于c,c依赖于A
一般来说,如果你问如何解决spring容器内部的循环依赖,肯定指的是默认单例Bean中属性互相引用的场景。也就是说,Spring的循环依赖是Spring容器注入时出现的问题。
2.Spring如何解决循环依赖
1、Spring中单例bean的三级缓存
2、Spring中Bean的生命周期
3.Bean初始化的主要方法
4. 具体说明
5. 插图
3、为什么要使用三级缓存?
1.使用一级缓存
实例化A -> 将半成品A放入singletonObjects -> 填写A的属性时,发现获取不到B -> 实例化B -> 从singletonObjects中取出A,填写B的属性 -> Put将成品B放入singletonObjects中->将B填充到A的属性中->将成品A放入singletonObjects中。
问题:这个基本过程是可以的,但是如果整个过程中另一个线程想要获取A,那么有可能只能获取到一个属性为空的半成品A,就会出现问题。
2.使用二级缓存
a) 使用 singletonObjects 和 EarlySingletonObjects
成品放在singletonObjects中,半成品放在earlySingletonObjects中。
流程可以是这样的:实例化A -> 将半成品A放入earlySingletonObjects -> 填充A的属性时,发现拿不到B -> 实例化B -> 将半成品A放入EarlySingletonObjects->从earlySingletonObjects中取出A并填充B的属性->将成品B放入singletonObjects中,并从其中删除B EarlySingletonObjects -> 将B填充到A的属性中 -> 将成品A放入singletonObjects中,并删除earlySingletonObjects。
问题:这个过程是线程安全的,但是如果给A添加一个切面(AOP),这种方式就不能满足需求,因为earlySingletonObjects存储的是所有原始对象,而我们需要注入的其实是A的代理对象。
b) 使用 singletonObjects 和 singletonFactories
成品放在singletonObjects中,半成品通过singletonFactories获取。
流程是这样的:实例化A -> 创建A的对象工厂,放入singletonFactories -> 填充A的属性时,发现无法获取B -> 实例化B -> 创建B的对象工厂并放入singletonFactories中 -> 从singletonFactories中获取一对A,就像一个工厂一样,获取A并将其填充到B中 -> 将成品B放入singletonObjects中,并从singletonFactories中删除B的对象工厂-> 将B填充到A的属性中 -> 将成品A放入singletonObjects中,并删除A工厂的对象。
问题:这个过程对于普通的IOC也适用,但是如果在A中添加一个切面(AOP),这种情况就不能满足需求了,因为每次通过singletonFactories.getObject()获取的代理对象都不一样。
终于
觉得好的朋友记得转发关注哦。后续我们将持续更新精选的技术文章!
本网站每日更新互联网创业教程,一年会员只需98,全站资源免费下载点击查看会员权益