SpringBoot修行之路-3.探秘SpringApplication

概述

一个标准的SpringBoot应用都具有如下类似代码:
在这里插入图片描述
这是我自己搭建的一个项目。里面只有一个注解@SpringBootApplication。这个注解有俩个作用:

  1. 标明这是一个SpringBoot应用
  2. 开启自动配置的功能

最后通过SpringApplication的run方法启动应用。这是我们使用SpringBoot应用的的时候最常用的代码。

SpringApplication

执行项目中的启动类的run方法后,就到了org.springframework.boot.SpringApplication的run方法。代码如下:
在这里插入图片描述
之后再继续调用run方法。如下:
在这里插入图片描述
这里创建了一个SpringApplication对象,然后执行run方法。关于SpringApplication对象属性简介,代码如下:
在这里插入图片描述
一些简单的注释我就直接放在截图里了,此处不再过多叙述。(ps:这个是我打断点的时候截的图)
自身的构造方法如下:
在这里插入图片描述
构造方法中初始化了一些属性。webApplicationType的属性具体实现是通过判断是否存在指定的类来赋值。代码如下:
在这里插入图片描述

在这里插入图片描述
属性mainApplicationClass是通过调用方法,判断是哪个调用了main方法来推断并设置项目main()方法启动的主程序启动类。代码如下:

在这里插入图片描述
简单的看完了以后,我们关注的重点是Initializers和Listeners 属性,俩者都是通过getSpringFactoriesInstances()方法获得不同类型的数组。
启动源码的测试案例就可以看到这俩个的值。Initializers属性的值如下:
在这里插入图片描述
Listenners属性在SpringBoot源码的测试用例中如下图:
在这里插入图片描述
这里简单说一下getSpringFactoriesInstances()方法。具体如下:在这里插入图片描述

主要是通过Sping.factories的配置文件来获取对应的值。这里names的值如下:org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

spring.factories部分内容截图如下:
在这里插入图片描述
创建对象createSpringFactoriesInstances()方法的代码具体实现如下:
在这里插入图片描述
排序方法就不在多说,此处是实现了Conparator进行排序。
那么此处实例化Application做了哪些事情呢?

  1. 将项目启动类的class设置为属性存储起来
  2. 设置应用类型
  3. 设置初始化器
  4. 设置监听器(初始化器和监听器最后在run方法中都会调用)
  5. 设置mainApplicationClass属性

创建完SpringApplication对象后,接下来看run方法。run方法整体逻辑较长。代码如下图:
在这里插入图片描述
从上述代码中可以看出,项目初始化启动大致包括以下几个部分:

  1. 获取并启动监听器
    getRunListeners(args)和listeners.starting()方法主要用于获取SpringApplication实例化过程中初始化的SpringApplicationRunListener监听器,并运行。getRunListeners(args)的代码具体实现如下:
    在这里插入图片描述
    也是通过getSpringFactoriesInstances()方法来获取一个SpringApplicationRunListener类型的监听器。

  2. 根据SpringApplicationRunListeners以及参数来准备环境
    prepareEnvironment(listeners,applicationArguments)方法主要用于对项目运行环境进行预设置,代码如下:
    在这里插入图片描述
    1. 根据不同的webApplicationType创建环境
    2. 加载指定的配置文件(包括多环境配置)
    3. 通知监听器,环境变量已经加载完成
    4. 最后将环境绑定到SpringApplication
    基本思路就是:创建环境,设置参数,通知监听器,绑定到SpringApplication
    然后,通过configureIgnoreBeanInfo(environment)方法排除一些不需要的运行环境

  3. 创建Spring容器
    根据webApplicationType判断,确定容器类型,如果是Servlet类型,则通过反射装载对应的字节码,也就是AnnotationConfigServletWebServerApplication.代码如下:
    在这里插入图片描述

  4. Spring容器的前置处理
    主要是在容器刷新前的操作,比如设置容器环境,包括各种变量。最关键的操作是:将启动类注入容器,为后续开启自动配置奠定基础。具体实现如下:
    在这里插入图片描述
    主要是对上下文进行一个预处理,比如监听器的响应事件,加载资源,设置上下文环境等等。

  5. 刷新容器
    开启刷新Spring容器,通过refresh方法对整个IOC容器的初始化(包括bean资源的丁文,解析,注册等),同时向JVM运行时注册一个关机钩子函数,在JVM关机时候能够关闭上下文,除非已经关闭。具体实现如下:
    在这里插入图片描述
    注:第四步和第五步就是用之前的context初始化设置的context(应用上下文环境),environment(项目运行环境),listeners(监听器),applicationArguments(项目参数),和printedBanner(项目图标信息)进行应用上下文的组装配置,并刷新配置。

  6. Spring容器的后置处理
    拓展接口,理由设计模式的模板方法,默认为空实现。如果有自定义需要,可以重新实现该方法。

  7. 发出结束执行的事件
    获取EventPublishingRunListener监听器,并执行started方法,并且将创建的Spring容器传进去,创建一个ApplicationStartedEvent事件,然后执行ConfigurableApplicationContext的publishEvent方法。也就是说在这里是在Spring容器中发布时间,前面的starting是直接向SpringApplication中的监听器发布启动事件。

  8. 执行Runners
    用于调用项目中自定义的执行器xxxRunners类,使得在项目启动完成后立即执行一些特点的程序。其中SpringBoot提供俩种执行器接口,分别是ApplicationRunner和CommandLineRunner。在使用时,只需要自定义一个执行器类实现其中的一个接口并重写对应的run方法接口,项目启动后悔立即执行这些特定的程序。实现如下:
    在这里插入图片描述
    总结一下,run方法的执行过程中,发生了什么事情。
    第一步:获取并启动监听器

    主要通过getSpringFactoriesInstances()方法来获取一个SpringApplicationRunListeners类型的监听器

    第二步:根据SpringApplicationRunListeners以及参数来准备环境:

    1.根据不同的webApplicationType创建环境
    2.加载配置文件
    3.通知监听器,环境变量准备完成
    4.将环境绑定到SpringApplication
    5.排除不需要的运行环境条件

    第三步:创建Spring容器。

    通过webApplicationType的不同类型创建ApplicationContext

    第四步:Spring容器的前置处理

    主要是对上下文进行一个预处理,比如监听器的响应时间,加载资源,设置上下文环境等等

    第五步:刷新容器

    开启刷新容器,对整个IOC容器进行初始化,并注册关机钩子函数

    第六步:后置处理

    空实现。使用设计模式的模板方法,可以自定义实现

    第七步:发出结束执行的事件

    这里主要是在Spring容器中发布事件,和前面的starting方法不一样,前面的是直接向SpringApplication中的监听器发布事件。

    第八步:执行Runners

    用于调用自定义的执行器,默认俩种执行器接口ApplicationRunner和CommandLineRunner。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值