Spring 三级缓存 实际上使用了3个Map 来打破单例对象循环依赖的问题,singletonObjects:这是一级缓存,保存已经实例化且完成了所有的依赖注入和初始化的单例bean实例。earlySingletonObjects:这是二级缓存,保存已经实例化但尚未完成所有的依赖注入和初始化的单例bean实例。它主要用于解决属性注入时的循环依赖问题。singletonFactories:这是三级缓存,保存创建单例bean实例的ObjectFactory。
通过代码仔细分析发现,如果不要singletonFactories这个第三级的缓存,也能解决循环依赖问题,那singletonFactories缓存存在的意义是什么,笔者经过查阅资料和思考分析后,总结原因如下:
1、违反了spring 对代理对象生成的原则,Spring 的设计原则是尽可能保证普通对象创建完成之后,再生成其 AOP 代理(尽可能延迟代理对象的生成),因为这样做的话,所有代理都提前到了实例化之后,初始化阶段前,显然与尽可能延迟代理对象的生成 原则是违背的。
2、防止因为提前被代理导致出现副作用,笔者认为这是最主要的原因。因为在bean对象实例后,还需要经过依赖属性的注入(populateBean方法)和初始化工作(initializeBean方法),特别是在初始化工作时,会进行调用BeanNameAware、BeanPostProcessor、InitializingBean、aop代理等一序列化工作,如果调用这些序列化工作的时候,就用代理对象来去执行调用,假设刚好这些方法被代理了,那就有可能执行这些初始化方法就包含有代理的逻辑在里面一起执行了,从而导致代理逻辑被误执行。