Spring 如何解决循环依赖?( 二 )

Spring 如何解决循环依赖?

文章插图
图片
进入 doCreateBean() 后 , 调用 addSingletonFactory() 。
Spring 如何解决循环依赖?

文章插图
图片
往三级缓存 singletonFactories 塞入 louzai1 的工厂对象 。
Spring 如何解决循环依赖?

文章插图
图片
Spring 如何解决循环依赖?

文章插图
图片
进入到 populateBean(),执行 postProcessProperties(),这里是一个策略模式,找到下图的策略对象 。
Spring 如何解决循环依赖?

文章插图
图片
正式进入该策略对应的方法 。
Spring 如何解决循环依赖?

文章插图
图片
下面都是为了获取 louzai1 的成员对象,然后进行注入 。
Spring 如何解决循环依赖?

文章插图
图片
Spring 如何解决循环依赖?

文章插图
图片
Spring 如何解决循环依赖?

文章插图
图片
Spring 如何解决循环依赖?

文章插图
图片
进入 doResolveDependency(),找到 louzai1 依赖的对象名 louzai2
Spring 如何解决循环依赖?

文章插图
图片
需要获取 louzai2 的 bean,是 AbstractBeanFactory 的方法 。
Spring 如何解决循环依赖?

文章插图
图片
正式获取 louzai2 的 bean 。
Spring 如何解决循环依赖?

文章插图
图片
到这里,第一层套娃基本结束,因为 louzai1 依赖 louzai2,下面我们进入第二层套娃 。
2.3 第二层
Spring 如何解决循环依赖?

文章插图
图片
获取 louzai2 的 bean,从 doGetBean(),到 doResolveDependency(),和第一层的逻辑完全一样,找到 louzai2 依赖的对象名 louzai1 。
前面的流程全部省略,直接到 doResolveDependency() 。
Spring 如何解决循环依赖?

文章插图
图片
正式获取 louzai1 的 bean 。
Spring 如何解决循环依赖?

文章插图
图片
到这里,第二层套娃结束,因为 louzai2 依赖 louzai1,所以我们进入第三层套娃 。
2.4 第三层
Spring 如何解决循环依赖?

文章插图
图片
获取 louzai1 的 bean,在第一层和第二层中,我们每次都会从 getSingleton() 获取对象,但是由于之前没有初始化 louzai1 和 louzai2 的三级缓存,所以获取对象为空 。
Spring 如何解决循环依赖?

文章插图
图片
Spring 如何解决循环依赖?

文章插图
敲重点!敲重点?。∏弥氐悖 。。?
到了第三层,由于第三级缓存有 louzai1 数据,这里使用三级缓存中的工厂 , 为 louzai1 创建一个代理对象,塞入二级缓存 。
Spring 如何解决循环依赖?

文章插图
图片
这里就拿到了 louzai1 的代理对象,解决了 louzai2 的依赖关系,返回到第二层 。
2.5 返回第二层返回第二层后,louzai2 初始化结束,这里就结束了么?二级缓存的数据,啥时候会给到一级呢?
甭着急 , 看这里,还记得在 doGetBean() 中,我们会通过 createBean() 创建一个 louzai2 的 bean,当 louzai2 的 bean 创建成功后 , 我们会执行 getSingleton(),它会对 louzai2 的结果进行处理 。
Spring 如何解决循环依赖?

文章插图
图片
我们进入 getSingleton(),会看到下面这个方法 。
Spring 如何解决循环依赖?

文章插图
图片
这里就是处理 louzai2 的 一、二级缓存的逻辑 , 将二级缓存清除,放入一级缓存 。
Spring 如何解决循环依赖?

文章插图
图片
2.6 返回第一层同 2.5,louzai1 初始化完毕后 , 会把 louzai1 的二级缓存清除,将对象放入一级缓存 。
Spring 如何解决循环依赖?

文章插图
图片
到这里,所有的流程结束,我们返回 louzai1 对象 。


推荐阅读