做汽配找哪个网站好,好品质高端网站设计推荐,wordpress登陆不进去,wordpress微云解析插件文章目录 #x1f504; 现实生活类比#xff1a;开餐厅的过程#x1f4a1; 结合到 Spring 三级缓存#x1f6e0;️ Spring 解决循环依赖的步骤1️⃣ Spring 开始创建 A2️⃣ Spring 开始创建 B3️⃣ B 创建完成后#xff0c;回过头来继续创建 A #x1f4cc; 三级缓存的作… 文章目录 现实生活类比开餐厅的过程 结合到 Spring 三级缓存️ Spring 解决循环依赖的步骤1️⃣ Spring 开始创建 A2️⃣ Spring 开始创建 B3️⃣ B 创建完成后回过头来继续创建 A 三级缓存的作用❓ 为什么不用两级缓存而要三级缓存 结论 现实生活类比开餐厅的过程
假设你是一个餐厅老板你有两个大厨 A 和 B他们互相配合做菜
A 需要 B 提供酱料B 需要 A 提供食材但 A 和 B 都必须先开工才能完成各自的任务。
如果他们都等对方的食材/酱料准备好餐厅就会卡死无法开张就像 Bean 创建时循环依赖
于是你Spring 容器设计了一个聪明的解决方案
先让 A 和 B 都开始工作即使他们还没完全准备好。让他们先把“半成品”存放在一个共享架子上这样可以让对方提前拿到需要的东西。等到他们各自的任务完成后再正式交付最终产品。
这个 共享架子就是 Spring 三级缓存的核心机制 结合到 Spring 三级缓存
现实餐厅Spring 三级缓存A 和 B 互相依赖但必须同时开始工作A 依赖 BB 依赖 A必须同时创建共享架子存放半成品方便对方使用二级缓存earlySingletonObjects存放半成品 Bean如果需要特别处理如食材加工可以先放入工厂区三级缓存singletonFactories存放 Bean 工厂 ️ Spring 解决循环依赖的步骤
假设 A 和 B 互相依赖Setter 方式Spring 解决循环依赖的过程如下
1️⃣ Spring 开始创建 A
发现 A 依赖 B于是暂停 A 的创建。先把 A 的“工厂”可以用来创建 A 的工具放入 singletonFactories 三级缓存。
2️⃣ Spring 开始创建 B
发现 B 依赖 ASpring 先去缓存里找 A。此时 A 还没完全创建但 Spring 可以从三级缓存里找到 A 的工厂并提前创建 A 的半成品然后存入 earlySingletonObjects 二级缓存。B 现在可以正常获取 A 了继续完成 B 的创建。
3️⃣ B 创建完成后回过头来继续创建 A
A 依赖的 B 现在已经创建好了A 终于可以完成创建并存入 singletonObjects一级缓存。B 也被放入一级缓存。
✅ 最终A 和 B 都成功创建没有死锁 三级缓存的作用
缓存作用何时使用一级缓存singletonObjects存放完全初始化的 BeanBean 创建完成后二级缓存earlySingletonObjects存放提前暴露的半成品 Bean解决循环依赖时但不支持代理三级缓存singletonFactories存放Bean 创建工厂用于创建代理对象如 AOP
如果有 AOP 代理Spring 会先从三级缓存拿出工厂创建代理对象再放入二级缓存保证最终拿到的 Bean 是代理对象而不是普通对象。 ❓ 为什么不用两级缓存而要三级缓存
如果只用二级缓存不使用三级缓存会有什么问题 无法支持 AOP 代理 。 代理对象是在Bean 创建完后才生成的如果没有三级缓存Spring 就没办法在 Bean 创建前插手进行代理。三级缓存允许 Spring 在代理对象生成前先存放一个“创建工厂”让 Spring 可以决定是返回原始对象还是代理对象。 结论
Spring 通过三级缓存singletonObjects、earlySingletonObjects、singletonFactories来解决 Setter 方式的循环依赖。一级缓存存放完全创建好的 Bean二级缓存存放提前暴露的半成品三级缓存存放 Bean 工厂支持 AOP 代理。如果 Bean 需要 AOP 代理Spring 先从三级缓存获取工厂创建代理对象然后存入二级缓存最终返回代理对象。构造器循环依赖无法通过三级缓存解决因为 Spring 不能提前暴露半成品。 总结一句话 Spring 通过共享“半成品”机制三级缓存让 A 和 B 在创建过程中互相提前看到对方避免循环等待从而成功创建