Spring框架如何解决Bean的循环依赖

1.什么是循环依赖?

        1.1定义

      循环依赖(Circular Dependency)指的是两个或多个类或组件彼此之间相互依赖,形成一个环状的依赖关系。这种情况下,如果不加以处理,就会导致依赖关系无法被正确地解析和初始化,从而引发程序运行时的问题或错误。例如,类A依赖于类B,而类B又依赖于类A,就形成了循环依赖。这种情况下,当系统尝试实例化类A时,需要先实例化类B,但实例化类B又需要实例化类A,就会导致一个无限循环或者无法顺利初始化的情况。

        1.2循环类型

多者相互依赖

3a4714fdc1d24a47abd3b77e641125a4.png

 

自身与自身依赖

d73758a0856a4f52a97d4a4900d60b5f.png

2.spring容器中bean的生命周期

        1,实例化

Spring容器将xml配置的的信息封装成一个BeanDefinition对象,存储到一个名为beanDefinitionMap的Map集合中去

        2,初始化

                属性填充(注入所依赖的属性值)[循环依赖问题所在]

                Aware接口属性注入

                执行BeanPostProcessor的before()方法

                执行InitializingBean接口的初始化方法

                执行 int-method自定义初始化方法

                执行BeanPostProcessor的after()方法

        3,使用操作

        4,销毁

               接口销毁

               属性销毁

 

3.循环依赖的过程:

        当A在初始化过程中需要B,但是singletonObjects中没有B , 此时,容器就会去创建B. 在创建B时又要去填充属性A , 但是singletonObjects中没有A,又会返回去创建A . 形成闭环循环往复 .( 自身与自身循环依赖时类似)

1bd99ff1e4a042d18caa2871b8e53a9c.png

 

4.Spring框架的解决方案:三级缓存

                        

        4.1 什么是三级缓存?

  1. 三级缓存(singletonObjects: 在早期阶段,Spring创建一个对象的实例, 但是这个对象并没有完全初始化. 这时候, Spring将这个对象实例放入三级缓存中. 在这个阶段, Spring会记录对象的引用, 但不会注入属性或调用任何初始化方法. 

  2. 二级缓存(earlySingletonObjects: 如果在依赖注入过程中发现循环依赖, Spring会在三级缓存中创建一个代理对象(proxy), 而不是真正的目标对象. 这个代理对象会暂时替代真实的对象引用,直到真实的对象初始化完成。

  3. 一级缓存(singletonFactories: 当对象的所有依赖关系都成功注入完成, 并且对象的初始化方法(如果有的话)被调用后, Spring将这个对象从三级缓存移到一级缓存中. 在这个阶段, 对象已经完全初始化, 可以安全地被其他对象引用和使用. 

        

        4.2 解决循环依赖过程

1.当A需要填充B时, 此时容器不仅会去创建B, 还会先将未完成的半成品A放在第三级缓存

a736e75efe5d4c2f8b69931ef4e85927.png2.在初始化B时, 会从三级缓存中拿取A , 并将A 放入二级缓存

4dc0bcfcb8fd4c63af4862ce4db1f9a0.png

3.B执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存并删除二三级缓存

367f6943d7874ba198b4a9bb48e70840.png

4.A从一级缓存拿取B注入 ,再执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,并删除二三级缓存

b5be7953f5254e799e3b3b338d01e568.png

 

至此,A B都完成Bean的创建

 

5.总结

三级缓存机制通过延迟Bean的完全初始化和使用代理对象的方式, 有效地解决了Spring中的循环依赖问题. 这种机制确保了对象依赖的正确注入顺序, 同时避免了初始化时可能导致的死锁或其他问题

 

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值