SpringBoot入坑指南之五:应用启动流程分析

原创
2019/02/15 16:14
阅读数 883

概述

Spring Boot框架带来一个Web应用启动的重大变化。 Java的Web应用部署都是通过容器,如:Tomcat、JBoss、Weblogic、Undertow等,一般都是将Java的Web应用构建成war、ear包再部署到相关的容器中。 Spring Boot带来了另外一种方式,就是可以将Web应用构建Jar包直接通过java命令启动,简化了应用的部署启动。这种启动方式底层技术并没有实际的变化,而是通过内嵌容器的方式取代外部容器,比如:spring-boot-starter-web默认使用Tomcat内嵌容器,你也可以选择使用其他内嵌容器。 在这篇文章里面主要是之前阅读了一些Spring Boot的启动源码,对Spring Boot启动流程作了一些简单的梳理。

Spring Boot应用启动方式

上文说到,Spring Boot的Web应用可以构建Jar包直接启动,即Spring Boot应用可以通过main方法直接启动,应用启动入口代码如下:

/**
 * @author: cent
 * @email: 292462859@qq.com
 * @date: 2019/2/9.
 * @description:
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

可以发现,Spring Boot应用启动入口代码非常简单,通过SpringApplication.run(Class<?> primarySource, String... args)方法启动,那么这个方法里面作用做了什么处理呢,下文主要就是对这个方法的源码进行简单的梳理~

Spring Boot应用启动解析

启动入口方法

Spring Boot启动核心方法代码如下,增加了简单注释,下文会对每一步骤进行简单解释:

public ConfigurableApplicationContext run(String... args) {
        //1.初始化计时器
        StopWatch stopWatch = new StopWatch();
        //2.计时器启动
        stopWatch.start();
        //Spring上下文对象
        ConfigurableApplicationContext context = null;
        //异常通知者列表
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        //3.设置系统配置java.awt.headless
        this.configureHeadlessProperty();
        //4.获取所有启动时监听器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //5.启动监听器
        listeners.starting();
         //定义异常通知者列表
        Collection exceptionReporters;
        try {
            //6.初始化应用启动参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //7.准备环境变量
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            //8.设置spring.beaninfo.ignore配置
            this.configureIgnoreBeanInfo(environment);
            //9.打印Banner
            Banner printedBanner = this.printBanner(environment);
            //10.创建上下文对象
            context = this.createApplicationContext();
            //11.获取Spring异常报告者Bean列表
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            //12.准备上下文对象
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //13.刷新上下文对象
            this.refreshContext(context);
            //14.刷新上下文对象后续工作
            this.afterRefresh(context, applicationArguments);
            //15.停止计时
            stopWatch.stop();
            //16.打印启动信息
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            // 17.执行启动时监听器started方法
            listeners.started(context);
            //18.执行ApplicationRunner和CommandLineRunner
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            //处理运行异常
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            //19.执行启动时监听器running方法
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            //处理运行异常
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

启动流程解释

进一步阅读启动源码,梳理Spring Boot应用启动流程如下图,下图对每个步骤进行简单分析并说明,详细的代码逻辑需要看一下源码。

Spring Boot启动流程图

尾巴

上面的内容是个人阅读源码分析的结果,可能存在错误之处,欢迎指正。上面的分析结果还比较表层,如果需要深入了解Spring Boot启动原理,建议深入研究一下里面的源码。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
7 收藏
分享
打赏
2 评论
7 收藏
0
分享
返回顶部
顶部