本文主要对refresh()方法作概览性的记录
refresh方法一共包含12步,概览如下:
(1)prepareRefresh()
- 本质没做啥,创建并设置了Environment对象
(2)obtainFreshBeanFactory()
- 新建或重建工厂:实例化 DefaultListableBeanFactory
- 设置 循环依赖 和 允许覆盖 两个参数
- 执行 loadBeanDefinitions(beanFactory)方法,这一步执行完后,配置文件中的bean都被解析完成,所有beanDefinition都被注册到了beanFactory.beanDefinitionMap中
- 值得注意的是,对于spring(非springboot)而言,这里注册了几个重要的类到beanDefinitionMap中
- ConfigurationClassPostProcessor:非常非常重要,本质是一个BeanDefinitionRegistryPostProcessor
- RequiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor:本质是BeanPostProcessor
(3)prepareBeanFactory(beanFactory)
//AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//1.调用本类方法:
// (1)设置容器的启动时间
// (2)设置活跃状态为true
// (3)设置关闭状态为false
// (4)获取Environment对象,并加载当前系统的属性值到Environment对象中
// (5)准备监听器和事件的集合对象,默认为空的集合
this.prepareRefresh();
//2.调用子类AbstractRefreshableApplicationContext.class的refreshBeanFactory()方法
// (1)如果工厂已经存在则销毁;
// (2)创建新的beanFactory:DefaultListableBeanFactory;
// (3)定制beanFactory,设置相关属性,设置是否允许覆盖和循环依赖;
// (4)调用子类AbstractRefreshableApplicationContext.class的loadBeanDefinitions(beanFactory)方法对bean进行注册;
// (4.1)实例化XmlBeanDefinitionReader并配置它的应用环境Environment,ResourceLoader,EntityResolver等初始化内容
// (4.2)调用loadBeanDefinitions(beanDefinitionReader)重要方法,构建DOM树,把beanDefinitions都注册到beanDefinationMap中去
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//3.调用本类方法:填充beanFactory的属性
// 初始化beanFactory中的一些基本参数
// (3.1)设置 BeanFactory 的classLoader为当前 context 的classLoader
// (3.2)设置 BeanFactory 的 BeanExpressionResolver(表达式语言处理器)
// (3.3)为BeanFactory增加一个默认的 propertyEditor,这个主要是对bean的属性等设置管理的一个工具类
// (3.4)添加一个 BeanPostProcessor:ApplicationContextAwareProcessor,此类用来完成某些Aware对象的注入
// (3.5)设置要一些忽略自动装配的接口
// (3.6)设置几个自动装配的特殊规则
// (3.7)添加一个 BeanPostProcessor:ApplicationListenerDetector
// (3.8)手动注册几个特殊的 系统环境bean 到一级缓存中
this.prepareBeanFactory(beanFactory);
try {
//4.AbstractApplicationContext中该方法是个空方法,留给子类进行扩展
//子类可以实现BeanPostProcess接口,spring里会进行回调
//在所有beanDefinition加载完成之后,bean实例化之前执行
//一般是为了修改bean definitions或者对BeanFactory做其他配置
this.postProcessBeanFactory(beanFactory);
//5. 这个方法中会去调用实现了BeanFactoryPostProcessor接口实现类的postProcessBeanFactory方法
this.invokeBeanFactoryPostProcessors(beanFactory);
//6.实例化并注册所有BeanPostProcessor beans
this.registerBeanPostProcessors(beanFactory);
//7.国际化
this.initMessageSource();
//8.初始化事件广播器。如果自定义了广播器,用自定义的
this.initApplicationEventMulticaster();
//9.空方法,留给子类来初始化其他bean
this.onRefresh();
//10.在所有注册的bean中查找listener bean,注册到消息广播器中
this.registerListeners();
//11.非常重要,实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean们)
//比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化 扫描的 @Bean之类的
//实例化的过程各种BeanPostProcessor开始起作用~~~~~~~~~~~~~~
this.finishBeanFactoryInitialization(beanFactory);
//12.//refresh做完之后需要做的其他事情
//清除上下文资源缓存(如扫描中的ASM元数据)
//初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
//发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}