Spring 只处理单例 Bean 的字段(或 Setter)注入出现循环依赖,对于构造器注入出现的循环依赖会直接抛出异常。还有就是如果是通过 denpends-on 配置的依赖出现了循环,也会抛出异常
Spring 处理循环依赖的解决方案如下:
Spring 在创建 Bean 的过程中,获取到实例对象后会提前暴露出去,生成一个 ObjectFactory 对象,放入 singletonFactories(三级 Map)中
在后续设置属性过程中,如果出现循环,则可以通过 singletonFactories(三级 Map)中对应的 ObjectFactory#getObject() 获取这个早期对象,避免再次初始化
三级缓存和ObjectFactory的延迟创建对象是解决循环依赖的核心
源码核心部分
从缓存中获取单例 Bean
会涉及到三个缓存
缓存指的就是下面三个 Map 对象:
singletonObjects(一级 Map):里面保存了所有已经初始化好的单例 Bean,也就是会保存 Spring IoC 容器中所有单例的 Spring Bean
earlySingletonObjects(二级 Map),里面会保存从 三级 Map 获取到的正在初始化的 Bean
singletonFactories(三级 Map),里面保存了正在初始化的 Bean 对应的 ObjectFactory 实现类,调用其 getObject() 方法返回正在初始化的 Bean 对象(仅实例化还没完全初始化好)

提前暴露当前 Bean

可以看到会将这个 ObjectFactory 往 singletonFactories (三级 Map)中存放
