SpringBoot运行流程源码分析:run方法流程及监听器

SpringBoot运行流程源码分析上一章中我们分析了 SpringApplication 类实例化的源代码 , 在此过程中完成了基本配置文件的加载和实例化 。 当 SpringApplication 对象被创建之后 ,通过调用其 run 方法来进行SpringBoot 的启动和运行 , 至此正式开启了 SpringApplication 的生命周期 。 本章介绍的内容同样是 Spring Boot 运行的核心流程之一 , 我们将会围绕 SpringApplicationRunListeners、ApplicationArguments、ConfigurableEnvironment 以及 应用上下文信息等部分展开讲解 。
run方法核心流程在分析和学习整个 run 方法的源代码及操作之前 , 我们先通过图 4-1 所示的流程图来看一下SpringApplication 调用的 run 方法处理的核心操作都包含哪些 。 然后 , 后面的章节我们再逐步细化分析每个过程中的源代码实现 。
SpringBoot运行流程源码分析:run方法流程及监听器文章插图
上面的流程图可以看出 , SpringApplication 在 run 方法中重 点做了以下操作 。
.获取监听器和参数配置 。
.打印 Banner 信息 。
.创建并初始化容器 。
监听器发送通知 。
当然 , 除了核心操作 , run 方法运行过程中还涉及启动时长统计、异常报告、启动日志、异常处理等辅助操作 。
对照流程图 , 我们再来整体看一下入口 run 方法的源代码 , 核心部分的功能已通过注释的形式进行说明 。
public ConfigurableApplicationContext run(String... args) {//创建 stopwatch 对象 ,用于统 i 计 run 方法启动时长StopWatch stopWatch = new StopWatch();//启动统计stopwatch.start();ConfigurableApplicationContext context = null;Collection except ionReporters = new Arraylist<>();//配置 headless 属性configureHeadlessProperty();//获得 SpringAppl icat ionRunL istener 数组//该数组封装 FSpringAppl icat ionRunL isteners 对象的 L isteners 中SpringApplicationRunListeners listeners = getRunListeners(args);//启动监听 , 遍历 SpringAppl icat ionRunL istener 数组每个元素 , 并执行listeners .starting();try {创建 Appl icat ionArguments 对象ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);//加载属性配置 , 包括所有的配置属性(如: appl icat ion. properties 中和外部的属性配置)Conf igurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);configureIgnoreBeanInfo( environment);//打 BannerBanner printedBanner = printBanner ( environment);//创建容器context = createApplicationContext();//异常报告器exceptionReporters = getSpringFactoriesInstances(Spr ingBootExcept ionReporter .class ,new Class[] { ConfigurableApplicat ionContext.class }, context);//准备容器 , 组件对象之间进行关联prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 初始化容器refreshContext(context);//初始化操作之后执行 , 默认实现为空afterRefresh( context, applicationArguments);//停止时长统计stopWatch. stop();//打印启动日志if (this. logStartupInfo) {new StartupInfoLogger(this . mainApplicat ionClass).logStarted(getApplicationLog(), stopwatch);//通知监昕器:容器启动完成listeners . started( context);//调用 Appl icat ionRunner 和 CommandL ineRunner 的运行方法 。 callRunners (context, applicat ionArguments);} catch (Throwable ex)//异常处理handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);try {//通知监听器:容器正在运行listeners . running( context);} catch (Throwable ex) {// 异常处理handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);return context;}