一、循环依赖场景
二、解决手段
- 三级缓存:
- singletonObjects: 一级缓存,用于保存实例化、注入、初始化完成的bean实例
- earlySingletonObjects: 二级缓存,用于保存实例化完成的bean实例
- singletonFactories: 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。
大致过程
- 在finishBeanFactoryInitialization中,开始初始化A,毋庸置疑通过反射
- 之后【非完美对象】开始设置属性字段,此时发现需要一个B的对象。同时已标记A处于正在初始化阶段
- 显然接下来,开始去初始化B的对象,同样的手法,到设置属性阶段,发现需要A对象
- 于是乎,spring又开始去初始化对象A的依赖,此时先从缓存singletonObjects去取,没有再去看是否正处于初始阶段,是则再从缓存earlySingletonObjects中取,再没有,则看是否存在allowEarlyReference,是则从singletonFactories中取
- 将早期对象A设置到B中,再把B设置到A中
- 可以使用@Lazy注解等延迟实例化的机制(不推荐) 蹩脚方式解决构造器级别的循环依赖
三、Refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//清空.class文件缓存,设置启动刷新时间,同时至标志位active true,closed false,初始化servlet属性源,验证必须存在的属性,初始化一个早期的事件收集器
prepareRefresh();
//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
//子类的refreshBeanFactory()方法启动
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//为BeanFactory配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
//为容器的某些子类指定特殊的BeanPost事件处理器
postProcessBeanFactory(beanFactory);
//调用所有注册的BeanFactoryPostProcessor的Bean
invokeBeanFactoryPostProcessors(beanFactory);
//为BeanFactory注册BeanPost事件处理器.
//BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
//初始化信息源,和国际化相关.
initMessageSource();
//初始化容器事件传播器.
initApplicationEventMulticaster();
//调用子类的某些特殊Bean初始化方法
onRefresh();
//为事件传播器注册事件监听器.
registerListeners();
//初始化所有剩余的单态Bean.
finishBeanFactoryInitialization(beanFactory);
//初始化容器的生命周期事件处理器,并发布容器的生命周期事件
finishRefresh();
}
catch (BeansException ex) {
//销毁以创建的单态Bean
destroyBeans();
//取消refresh操作,重置容器的同步标识.
cancelRefresh(ex);
throw ex;
}
}
}