做 Java 开发的,一样平常都绕不开 Spring,那么面试中肯定会被问到 Spring 的相干内容,而循环依赖又是 Spring 中的高频面试题
这不前段时间,我的一朋侪去面试,就被问到了循环依赖,结果他还在上面还小磕了一下,他们谈天过程如下
面试官:说下什么是循环依赖
朋侪: 两个或则两个以上的对象互相依赖对方,最终形成 闭环 。比方 A 对象依赖 B 对象,B 对象也依赖 A 对象
将 成品 circle 放到了一级缓存中,二级缓存中的 circle 没有用到就直接 remove 了,最后各级缓存中的数据信任各人都清楚了,就不展示了
我们回顾下这种环境下各级缓存的存在感,一级缓存存在感十足,二级缓存可以说无存在感,三级缓存有存在感(向 loop 中填充 circle 的时间有用到)
所以此种环境下:可以淘汰某个缓存,只需要两级缓存就够了
循环依赖 + AOP
代码还是非常简单:spring-circle-aop,在循环依赖的基础上加了 AOP
比上一种环境多了 AOP,我们来看看对象的创建过程有什么不一样;同样是先创建 Circle ,在创建 Loop
创建过程与上一种环境大要一样,只是有小部分区别,跟源码的时间我会在这些区别上有所停顿,其他的会跳过,各人要细致看
实例化 Circle ,然后填充 半成品 circle 的属性 loop ,去 Spring 容器中获取 loop 对象,发现没有
则实例化 Loop ,接着填充 半成品 loop 的属性 circle ,去 Spring 容器中获取 circle 对象
我们发现从第三级缓存获取 circle 的时间,调用了 getEarlyBeanReference 创建了 半成品 circle 的代理对象
将 半成品 circle 的代理对象放到了第二级缓存中,并将代理对象返回赋值给了 半成品 loop 的 circle 属性
注意:此时是在进行 loop 的初始化,但却把 半成品 circle 的代理对象提前创建出来了
loop 的初始化还未完成,我们接着往下看,又是一个重点,细致看
我们回顾下这种环境下各级缓存的存在感,一级缓存还是存在感十足,二级缓存有存在感,三级缓存挺有存在感
第三级缓存提前创建 circle 代理对象,不提前创建则只能给 loop 对象的属性 circle 赋值成 半成品 circle ,那么 loop 对象中的 circle 对象就无 AOP 加强功能了
第二级缓存用于存放 circle 代理,用于解决循环依赖;也许在这个示例表现的不够显着,因为依赖比较简单,依赖稍复杂一些,就能感受到了