Spring是个大鱼缸 我们要在里面养鱼!
AB循环依赖情况:只要A注入方式是setter并且singleton就不会有循环依赖问题 但是用构造函数不行
Spring容器内部是用三级缓存在解决循环依赖的-DefaultSingletonBeanRegistry
(成品)一级缓存是singletonObject是 存放已经经历了完整生命周期的Bean对象 -- 单例池
(半成品)二级缓存是 earlySingletonObject 存放早起暴露出来的Bean对象,Bean的生命周期未结束
(准备生产的)第三级缓存是Map<String,ObjectFactory>singletonFactores 存放可以生成Bean的工厂
只有单例的bean才会通过三级缓存提前暴露 来解决循环依赖问题 而非单例每次获取的都是一个新对象 都会重新创建 所以是没有缓存的 不需要通过三级缓存
三个map 四大方法
四大方法:找得到就直接用 找不到就创建
创建的话 要给A做属性创建 然后属性创建的时候呢 (A里面是需要填充B的 所以我们又重新走A的路子去创建B )
A和B都是从三级慢慢的变成了一级,从工厂生成变成了成品
有点像递归
1. A 创建过程中需要 B,于是 A 将自己放到三级缓里面,
去实例化 B
2 B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个 A 放到二级缓存里面,并删除三级缓存里面的 A
3 B 顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)然后回来接着创建 A,此时 B 已经创建结束,直接从一级缓存里面拿到 B,然后完成创建,并将A自己放到一级缓存里面
A与B 你中有我 我中有你
怎么解决循环依赖? 首先看是否存在该类的单例bean,如果不存在,就去创建,然后创建过程中去填充属性 然后放进池子里 最终放到一级缓存,最后暴露给用户去使用
为什么一定要用三级缓存?
Spring解决循环依赖主要靠的是Bean的“中间态”这个概念,中间态就代表已经实例化但还没有初始化的状态----半成品
跟AOP有关系,在B去获取A的时候会判断是否有AOP代理,如果有,则要先经过AOP代理完再给B