` public void refresh() throws BeansException, IllegalStateException {
this.startupShutdownLock.lock();
try {
// 启动关闭线程,这个线程用来表示启动当前容器使用的线程
// 该成员变量在之前的版本中并不存在,也是为了支持后续的并发实例化bean的情况
this.startupShutdownThread = Thread.currentThread();
// StartupStep是个小工具,用来记录执行流程
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 为当前上下文进行刷新前的准备
prepareRefresh();
// 此处是要初始化一个bean工厂,实时上beanFactory会在上下文构建的就创建了
// 核心的目的是为了提供一种可以进行重复刷新的bean工厂的扩展,虽然我们不用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为工厂做一些准备工作,完成一些核心的基础配置
// 这是spring-framework需要做的工作
prepareBeanFactory(beanFactory);
try {
// 空方法,留给子类去实现,GenericXmlApplicationContext没有进行扩展
// GenericWebApplicationContext进行了扩展,注册了新的作用域,处理了和servlet相关的一些工作
// 此处是spring提供给第三方的框架如spring-mvc等在容器启动前做的配置性工作
postProcessBeanFactory(beanFactory);
// 记录新的步骤,post-process
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用所有beanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的实现类,此时bean没有进行实例化
// 我们可以在此处配置beanFactory,修改beanDefinition
// 此处会处理BeanDefinitionRegistryPostProcessor
// 执行流程会根据priorityOrdered Ordered noOrdered进行排序
// 单独添加了一个listener的探测器,会在bean实例化后判断是否是一个listener,如果是进行注册
invokeBeanFactoryPostProcessors(beanFactory);
// 注册beanPostProcessor,同样会根据priorityOrdered Ordered noOrdered进行排序
registerBeanPostProcessors(beanFactory);
// 结束步骤
beanPostProcess.end();
// 初始化上下文的messageSource
initMessageSource();
// 初始化上下文的多播器
initApplicationEventMulticaster();
// 留出空方法,让子类扩展
// ServletWebServerApplicationContext进行了扩展,创建一个webServer,启动tomcat
onRefresh();
// 注册监听器,此处listenerBean不会被实例化,会议beanName的方式注册
// 还会处理一些早期事件
registerListeners();
// 核心:实例化所有的非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
// 完成刷新,发布完成刷新的事件
finishRefresh();
}
// 捕获运行时异常和错误
catch (RuntimeException | Error ex ) {
// 如果日志器支持警告级别,则记录异常信息
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例,以避免资源泄露
destroyBeans();
// 重置'active'标志
cancelRefresh(ex);
// 将异常抛给调用者
throw ex;
}
// 无论是否抛出异常,都会执行的代码块,用于清理工作
finally {
contextRefresh.end(); // 结束上下文刷新过程
}
}
// 无论是否抛出异常,都会执行的代码块,用于释放资源
finally {
this.startupShutdownThread = null; // 重置启动/关闭线程
this.startupShutdownLock.unlock(); // 解锁启动/关闭锁
}
}`
标签:beanFactory,spring,流程,启动,bean,线程,上下文
From: https://www.cnblogs.com/jichenghui/p/18352252