接着昨天的调试,今天继续分析AbstractApplicationContext的refresh方法:
先看prepareRefresh方法:
doc介绍:为更新准备好context,设置启动日期和激活标志位同时执行属性源的初始化。
实现细节:设置当前时间为启动日期,设置指示context是否已经关闭的标志位closed为false,设置指示当前context是否已经启动的标志位active为true,初始化context的environment中所有默认的属性源(方法默认没有任何实现),验证所有需要的属性是否支持解析,当多路广播multicaster可用时允许早期应用事件集合被发送。
再看obtainFreshBeanFactory方法:该方法是通知子类去更新内部的bean工厂,此处的子类GenericApplicationContext没有实际的更新实现。
再看prepareBeanFactory方法:
doc介绍是:为容器准备可用的bean工厂,配置工厂的标准容器特性,如容器的ClassLoader和post-processors。
实现细节:设置ClassLoader,设置标准的bean表达式解析器,添加基于给定的ResourceLoader和PropertyResolver资源编辑器的注册器,添加ApplicationContextAwareProcessor,设置不需要自动注入的类,注册可解析的依赖包括消息源(这些自动注册的类不被认为是bean,如容器本身),注册early post-processor用于检测内部bean为ApplicationListeners,添加可能存在的LoadTimeWeaver(如果存在,需要设置临时的ClassLoader用于类型匹配),注册默认的environment beans。
再看postProcessBeanFactory方法:
doc介绍:允许context子类中bean factory的post-processing,可在标准初始化后修改应用context的内部bean factory,所以的bean定义都会被加载但还没有初始化完全。
接下来是invokeBeanFactoryPostProcessors方法:
doc介绍:初始化并唤醒所有已经注册的BeanFactoryPostProcessor。
接着是registerBeanPostProcessors方法:
doc介绍:初始化并唤醒所有已经注册的BeanPostProcessor。注意区分于上一个方法。
接着是初始化消息源,初始化ApplicationEventMulticaster,初始化其他基于特定context子类的特殊的beans,检查设置的监听器并注册,初始化剩余的所有非懒加载单例beans结束容器bean factory的初始化。
最后是finishRefresh方法:
doc介绍:完成容器的更新refresh,唤醒LifecycleProcessor的onRefresh方法,发布ContextRefreshedEvent事件。
实现细节:清理容器基本的资源缓存(如来自扫描的ASM元数据),初始化LifecycleProcessor,调用其onRefresh方法,发布ContextRefreshedEvent,加入已启动的LiveBeansView MBean。
contex更新完毕后可以注册shutdownHook,用于JVM关闭是关闭context。
回到run方法,进入SpringApplication的afterRefresh方法,此方法在此SpringApplication暂时没有实现,继续run方法,停止stopWatch,打印SpringApplication完全启动时的时间日志,开启SpringApplicationRunListeners,发送SpringApplication started事件,进入callRunners方法:
实现细节:添加需要的Runner,将其排序,然后按顺序调用。Runner是一个当bean已经包含在SpringApplication中后指示该bean运行的接口。
接着如果以上所有方法都运行正常,没有报异常的话,进入listeners.running方法:发布ApplicationReadyEvent事件。如果发生了异常,进入handleRunFailure方法:
实现细节:捕获并处理异常,然后报告异常。
至此,run方法调用完成,返回,剩余的方法也全部完成,统统返回,回调程序入口:
结束调试。
这次调试的是不基 WebApplication的SpringBoot原始应用,下次有时间调试下WebApplication基于Servlet和Reactive的SpringBoot应用。