Java面试题

题目

Spring 循环依赖是什么样的场景,怎么解决循环依赖?为什么是三级缓存而不是二级缓存?

答案

循环依赖的场景是有两个类对象 A 和 B。在初始化 A 的时候发现需要依赖 B,这个时候就会初始化 B,然后在 B 里面会依赖 A 的对象。这个时候就会发生循环依赖的情况。

  1. 初始化对象是根据构造函数初始化,那么循环依赖是没有办法解决的,spring 会抛出异常。
  2. 初始化对象是根据属性 set 注入的话,spring 这边会创建三级缓存,分别为:singletonFactories,earlySingletonObjects,singletonObjects。当创建 A 的对象的时候,发现依赖 B 的对象,这个时候创建 B 的对象,将 A 创建好的临时对象存放在 singletonFactories 中,在创建 B 对象的时候发现依赖 A 对象,则首先从 singletonObjects 获取,发现 A 对象不存在,就从 earlySingletonObjects 也不存在,就从 singletonFactories 获取。这个时候获取到,就会将 A 创建好的对象存放在 earlySingletonObjects 中,然后 B 创建完毕后再创建 A,A 创建完毕后从 earlySingletonObjects 移到 singletonObjects 中。

用三级缓存而不是二级缓存是因为在将对象从三级缓存放入二级缓存的时候,会有一个 SmartInstantiationAwareBeanPostProcessor 这样的后置处理器,给用户提供了扩展接口。