面试官提问
● 什么是循环依赖?可以举个例子吗?
● Spring是怎么解决循环依赖的?
● Spring使用第三级缓存主要是为了解决什么问题?
Spring Bean 循环依赖是指两个以上的 Bean 互相持有对方而形成循环。比如 A 依赖 B,B 依赖 A。Spring Bean 循环依赖问题是通过三级缓存和引用提前暴露机制来解决的:
● singletonObjects:一级缓存,存储经历了完整生命周期的 Bean 对象。
● earlySingletonObjects:二级缓存,存储提前暴露出来的 Bean 对象,其生命周期未结束,属性未完全填充。
● singletonFactories:三级缓存,存储生成 Bean 的工厂。
若A和B互相依赖,则利用三级缓存实现Bean装配的过程如下:
步骤01 A 实例化过程中发现依赖 B,于是先将 A 存储在三级缓存,然后去实例化 B。
步骤02 B 实例化的过程中发现需要 A,于是 B 首先在一级缓存中查询A,若一级缓存中不存在,则继续查询二级缓存,若二级缓存中不存在,则继续查询三级缓存,最终匹配到 A,然后将三级缓存中的 A 清楚并转移至二级缓存。
步骤03 B匹配到A后完成实例化,将自己存储在一级缓存中,此时B依赖的A属于提前暴露出来的Bean,接下来需要继续完成A的实例化,此时,可以从一级缓存中获取B来完成A的最终创建,实例化完成后A被放入一级缓存。