一、三级缓存
Spring提供了三级缓存存储完整Bean实例和半成品Bean实例列,用于解决循环引用问题,
在DefaultListableBeanFactory的上四级父类DefaultSingletor BeanRegistry中提供如下三个Map:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** 一级缓存,最终存储单例bean的容器,即实例化和初始化都完成的bean对象 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存,早期bean单例池,缓存半成品对象,且当前对象已经被其它对象引用*/
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** 三级缓存,单例bean的工厂池,缓存半成品对象,对象未被引用,使用时再通过工厂创建bean*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}
二、解决循环依赖
如果此时有两个bean对象UserService和UserDao,相互引用,可以参照下面的简图分析:
UserService和UserDao循环依赖的过程描述:
- UserService实例化对象,但尚未初始化,将UserService存储到三级缓存中;
- UserService属性注入时需要UserDao,此时去缓存中获取,发现没有UserDao;
- 进行UserDao对象实例化,但尚未初始化,将UserDao存储到到三级缓存中;
- UserDao属性注入,需要UserService,从三级缓存获取UserService,UserService从三级缓存移入二级缓存;
- UserDao执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存;
- UserService注入UserDao;
- UserService执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存。