手写 Spring 循环依赖¶
一、场景¶
A 依赖 B,B 依赖 A。
二、手写一个简化版¶
public class MyContainer {
Map<String, Object> singletonObjects = new HashMap<>();
Map<String, Object> earlyObjects = new HashMap<>();
public Object getBean(String name) {
// 1. 完整 Bean
if (singletonObjects.containsKey(name))
return singletonObjects.get(name);
// 2. 早期 Bean(半成品)
if (earlyObjects.containsKey(name))
return earlyObjects.get(name);
// 3. 实例化
Object bean = createInstance(name);
earlyObjects.put(name, bean);
// 4. 属性填充
populateBean(bean);
// 5. 完成
singletonObjects.put(name, bean);
earlyObjects.remove(name);
return bean;
}
}
三、执行流程¶
创建 A¶
- getBean("A")。
- 实例化 A,放 earlyObjects。
- populateBean(A),发现需要 B。
- getBean("B")。
创建 B¶
- getBean("B")。
- 实例化 B,放 earlyObjects。
- populateBean(B),发现需要 A。
- getBean("A")。
- earlyObjects 有 A,返回半成品 A。
- B 拿到 A,属性填充完成。
- singletonObjects 放 B。
回到 A¶
- A 拿到 B,属性填充完成。
- singletonObjects 放 A。
四、这就是二级缓存¶
earlyObjects 就是二级缓存。
五、为什么 Spring 要三级¶
如果 A 被 AOP 代理,B 应该拿到代理对象,不是原始 A。三级缓存的 ObjectFactory 决定"要不要提前生成代理"。
一句话
手写循环依赖 = 实例化后先放 Map,填充时从 Map 拿。