十分钟带你了解SpringBoot启动流程

话不多说我们直接看流程图

1、运行 SpringApplication.run() 方法

        springboot的应用程序是从run方法开始的。

2、确定应用程序类型

这个过程非常重要,直接决定了项目的类型,应用类型分为三种,都在WebApplicationType这个枚举类中,如下:

  • NONE:顾名思义,什么都没有,正常流程走,不额外的启动web容器,比如Tomcat
  • SERVLET:基于servlet的web程序,需要启动内嵌的servletweb容器,比如Tomcat
  • REACTIVE:基于reactive的web程序,需要启动内嵌reactiveweb容器。

3、加载所有的初始化器

初始化器ApplicationContextInitializer用于IOC容器刷新之前初始化一些组件,比如ServletContextApplicationContextInitializer,那么这个文件在哪呢?自带有2个,分别在源码的jar包 spring-boot 项目 和 spring-boot-autoconfigure 项目 里面各有一个。

具体位置:当然,也可以自己实现一个自定义的初始化器:实现 ApplicationContextInitializer接口既可

4、加载所有的监听器

加载监听器也是从 META-INF/spring.factories 配置文件中加载的,与初始化不同的是,监听器加载的是实现了 ApplicationListener 接口的类,监听器主要用于监听特定的事件,比如IOC容器刷新、容器关闭等。

5、设置程序运行的主类

deduceMainApplicationClass(); 这个方法仅仅是找到main方法所在的类,为后面的扫包作准备,deduce是推断的意思,所以准确地说,这个方法作用是推断出主方法所在的类。


到这里呢实际上才完成流程图的第一步,上面分析了SpringApplication的构建过程,一切都做好了铺垫,现在到了启动的过程了。

1.获取、启动运行过程监听器

public interface SpringApplicationRunListener {

    // 在run()方法开始执行时,该方法就立即被调用,可用于在初始化最早期时做一些工作
    void starting();
    // 当environment构建完成,ApplicationContext创建之前,该方法被调用
    void environmentPrepared(ConfigurableEnvironment environment);
    // 当ApplicationContext构建完成时,该方法被调用
    void contextPrepared(ConfigurableApplicationContext context);
    // 在ApplicationContext完成加载,但没有被刷新前,该方法被调用
    void contextLoaded(ConfigurableApplicationContext context);
    // 在ApplicationContext刷新并启动后,CommandLineRunners和ApplicationRunner未被调用前,该方法被调用
    void started(ConfigurableApplicationContext context);
    // 在run()方法执行完成前该方法被调用
    void running(ConfigurableApplicationContext context);
    // 当应用运行出错时该方法被调用
    void failed(ConfigurableApplicationContext context, Throwable exception);
}

 

①如何获取运行监听器?

SpringApplication#run()方法中,源码如下:

//从spring.factories中获取监听器
SpringApplicationRunListeners listeners = getRunListeners(args);

跟进getRunListeners()方法,其实还是调用了loadFactoryNames()方法从spring.factories文件中获取值,如下:

org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

最终注入的是EventPublishingRunListener这个实现类,创建实例过程肯定是通过反射了,因此我们看看它的构造方法,如下图:

 this.application = application——保存创建好的SpringApplication。

this.args = args——构建一个简单应用事件广播器。

this.initialMulticaster.addApplicationListener(listener)——将SpringApplication创建过程中设置的监听器全部添加到广播器中。

②如何启动运行监听器?

SpringApplication#run()方法中,源码如下:

//执行starting()方法
listeners.starting(bootstrapContext, this.mainApplicationClass);

执行SpringApplicationRunListenersstarting()方法,跟进去其实很简单,遍历执行上面获取的运行监听器,这里只有一个EventPublishingRunListener。因此执行的是它的starting()方法,源码如下图:

小结

这一步其实就是广播了ApplicationStartingEvent事件来触发监听这个事件的ApplicationListener

因此如果自定义了 ApplicationListener并且监听了 ApplicationStartingEvent(应用程序开始启动)事件,则这个监听器将会被触发。

 

2. 环境构建

这一步主要用于加载系统配置以及用户的自定义配置(application.properties),源码如下,在run()方法中:

ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);

prepareEnvironment方法内部广播了ApplicationEnvironmentPreparedEvent事件,源码如下图:

 


剩下的步骤本章不做太多叙述,仅给大家了解,想吃透springboot的启动流程,可以浏览:

9千字长文带你了解SpringBoot启动过程--史上最详细 SpringBoot启动流程-图文并茂_Fly丶X的博客-CSDN博客

 3. 创建IOC容器

4. IOC容器的前置处理

        调用初始化器

        加载启动类,注入容器

        两次广播事件

5. 刷新容器

6. IOC容器的后置处理

7. 发出结束执行的事件

8. 执行Runners

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值