spring循环依赖的解决方案(“三级缓存”)

spring循环依赖的解决方案(“三级缓存”)

1.循环依赖的由来

循环依赖的由来就是两个类都需要对方去声明一个成员属性。这种互相需求会陷入一种死结,假设有A、B两个类,A在初始化时需要加载一个点B,然后B在加载时又需要一个A,然后又回到A的加载,最终直接崩溃。

2.“三级缓存”解决循环依赖

1)“三级缓存”由来

在Spring框架中,特别是在Spring的Bean生命周期和依赖注入(DI)过程中,并没有直接称为“三级缓存”的官方术语。然而,在讨论Spring的Bean创建和依赖注入的上下文时,特别是在Spring的AbstractApplicationContextAbstractAutowireCapableBeanFactory类中,我们可以看到与缓存相关的几个关键组件,这些组件在Bean的创建和解析依赖时起到了重要作用。这些组件通常被非正式地称为“缓存”,但它们实际上并不直接对应于传统意义上的缓存机制(如LRU缓存)。尽管没有明确的“三级缓存”定义,但我们可以从Spring的Bean创建过程中识别出几个关键的“存储”或“缓存”点,这些点对于理解Spring如何处理Bean的依赖和生命周期至关重要。

2)单例对象缓存

Singleton Objects Cache(单例对象缓存):这是最直接与“缓存”相关的部分。Spring容器中的单例Bean(默认作用域为singleton)在创建后会被存储在这个缓存中。当再次请求同一个Bean时,Spring会直接从缓存中返回已存在的Bean实例,而不是重新创建。

3)早期单例对象缓存

Early Singleton Objects Cache(早期单例对象缓存):在Bean的创建过程中,如果Bean之间存在循环依赖,Spring会使用这个缓存来存储尚未完全初始化的Bean实例。这允许Spring在解决循环依赖时,能够返回Bean的早期引用(即尚未完全初始化的Bean实例)。这个缓存是Spring处理循环依赖的关键机制之一。

3) 单例工厂缓存

Singleton Factories Cache(单例工厂缓存):这个缓存存储的是创建Bean实例的工厂对象,而不是Bean实例本身。当Bean的创建依赖于其他尚未创建的Bean时,Spring可能会使用这些工厂来延迟Bean的创建,直到所有依赖项都可用。这有助于解决复杂的依赖关系,特别是在存在循环依赖的情况下。
虽然这些组件通常不被直接称为“三级缓存”,但它们共同构成了Spring处理Bean生命周期和依赖注入的关键机制。了解这些组件的工作原理对于深入理解Spring框架的内部机制至关重要。

3.总结

spring主要就是通过半成品替代的方式来解决循环依赖的。回到上面,A、B循环依赖的问题,在加载时,当初始化a时,先去一级缓存中查找有没有a对象,有就直接返回。没有则将a的实例化工厂放入三级缓存中,实例化a。发现a需要b对象,就先从一二级缓存中查找b,如果找到b对象就直接返回给,如果没有就将b对象的实例化工厂放入三级缓存,实例化b。发现b需要a对象,就先从一二级缓存中查找a,没有就回去继续初始化a,通过实例化工厂生成一个未装配属性的半成品a对象放入二级缓存,再将三级缓存中的a工厂删除。然后再去实例化b,将半成品a装配,将b对象放入一级缓存中,删除二三级缓存中的b对象,再去初始化a,将一级缓存中的b装配进a,将a放入一级缓存,删除二级缓存中的a对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值