Spring是如何解决循环依赖的 小记

提到Spring的循环依赖,便先从Spring的生命周期开始时说起。

Spring框架的生命周期:

        1.实例化(Instantiation):在这一阶段,Spring 容器根据配置文件或注解创建 Bean 的实例。可以使用构造函数实例化对象或通过工厂方法创建对象。

        2.属性赋值(Population):在实例化后,Spring 容器通过依赖注入(Dependency Injection)或者设置属性(Property Setting)为 Bean 的属性赋值

        3.初始化前回调(Initialization Callbacks):在 Bean 的属性赋值完成后,Spring 容器可以调用自定义的初始化方法。可以通过实现 InitializingBean 接口或使用 init-method 属性来定义 Bean 的初始化方法

        4.使用:在初始化完成后,Bean 可以被应用程序使用。

        5.销毁(Bean Destruction):当应用程序关闭时,Spring 容器可以销毁管理的 Bean 对象。通过调用 Bean 的销毁方法来完成资源释放、关闭数据库连接等操作

Spring 容器管理的 Bean 生命周期是由容器负责管理的。在单例作用域下,Bean 的创建和初始化只会发生一次,并且销毁时也是容器处理。

Spring的依赖注入:

        在Spring中,创建Bean的方式基本是通过调用BeanFacotry的getBean()方法来进行创建的,在常用的实现了ApplicationContext接口的高级容器的内部都创建了一个BeanFacoty的实例。

Spring的注入方式有:

         xml方式依赖注入:通过xml文件配置进行注入;

        注解方式依赖注入:例如通过@Autowired方式注入;

在创建类对象时会根据属性到容器中获取注入的对象从而创建并装配到类对象中。

Spring通过引入三级缓存的机制来解决循环依赖

借用图

一级缓存:即单例对象缓存池,beanName->Bean,其中存储的就是实例化,属性赋值成功之后的单例对象。
二级缓存:早期的单例对象,beanName->Bean,其中存储的是实例化之后,属性未赋值的单例对象,执行了工厂方法生产出来的Bean,bean被放进去之后, 当bean在创建过程中,就可以通过getBean方法获取到早期单例对象。
三级缓存:单例工厂的缓存,beanName->ObjectFactory,添加进去的时候实例还未具备属性,用于保存beanName和创建bean的工厂之间的关系map
 Spring 解决循环依赖的简要流程:

        1.创建对象实例:当 Spring 容器初始化时,如果检测到需要创建一个新的对象实例,它会首先尝试从一级缓存中获取对象实例。如果没有找到,它将继续执行下一步。

        2.提前暴露未完成的对象:创建对象实例时,Spring 会在二级缓存中提前将正在创建的对象实例放置于缓存中,并标记为未完成状态。这样,其他对象在引用该对象时,可以获取到一个未完成的引用

        3.属性注入:当对象实例被创建到一定程度时,Spring 会开始注入该对象的属性。如果发现需要注入的属性类型是另一个正在创建的对象,并且该对象在二级缓存中,那么 Spring 会从二级缓存中获取该对象实例,并将其注入到当前对象的属性中。

        4.对象初始化:当对象实例创建完成后,Spring 会执行该对象的初始化方法,并且将其标记为已完成状态。

        5.解决循环依赖:如果发现另一个正在创建的对象依赖于当前对象,并且当前对象已经在二级缓存中标记为未完成状态,Spring 将会从三级缓存中获取已经创建的对象实例(只是未完成状态),并注入到另一个对象的依赖属性中。这样,循环依赖就得到了解决。

        需要注意的是,Spring 通过使用三级缓存来解决循环依赖时,要求循环依赖的对象必须使用默认的无参构造函数创建。否则,在创建对象实例时可能引发其他问题。因此,在设计对象之间的依赖关系时,需要特别注意避免产生复杂的循环依赖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值