一、Bean的循环依赖
1.1 自我依赖 A依赖A
1.2 A、B互相依赖
1.3 三者或多者依赖
二、三级缓存解决
2.1 只有一级缓存不能解决
分析一级缓存这样存放成品 Bean
的流程中,是不能解决循环依赖的问题的。
因为 A 的成品创建依赖于 B,B的成品创建又依赖于 A,当需要补全B的属性时 A 还是没有创建完,所以会出现死循环。
2.2 二级缓存能解决吗?
- 有了二级缓存其实这个事处理起来就容易了,
一个缓存用于存放成品对象
,另外一个缓存用于存放半成品对象
。 - A 在创建半成品对象后存放到缓存中,接下来补充 A 对象中依赖 B 的属性。
- B 继续创建,创建的半成品同样放到缓存中,在补充对象的 A 属性时,可以从半成品缓存中获取,现在 B 就是一个完整对象了,而接下来像是递归操作一样 A 也是一个完整对象了。
2.3 三级缓存解决什么?
- 有了二级缓存都能解决 Spring 依赖了,怎么要有三级缓存呢。其实我们在前面分析源码时也提到过,三级缓存主要是解决 Spring AOP 的特性。
- AOP 本身就是对方法的增强,是 ObjectFactory<?> 类型的 lambda 表达式,而 Spring 的原则又不希望将此类类型的 Bean 前置创建,所以要存放到三级缓存中处理。
- 其实整体处理过程类似,唯独是 B 在填充属性 A 时,先查询成品缓存、再查半成品缓存,最后在看看有没有单例工程类在三级缓存中。最终获取到以后调用 getObject 方法返回代理引用或者原始引用。至此也就解决了 Spring AOP 所带来的三级缓存问题。本章节涉及到的 AOP 依赖有源码例子,可以进行调试
为什么非得要三级缓存(因为有的Bean对象是有AOP,需要代理的)
比如A对象是一个被AOP增量的对象,B依赖A时,得到的A肯定是代理对象;而三级缓存的Value是ObjectFactory,可以从里面拿到代理对象