SpringBoot启动过程探究及配置文件优先级解析

这篇具有很好参考价值的文章主要介绍了SpringBoot启动过程探究及配置文件优先级解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

构造SpringApplication对象

推测web应用类型

  1. 如果项目依赖中存在org.springframework.web.reactive.DispatcherHandler,并且不存在org.springframework.web.servlet.DispatcherServlet,那么应用类型为WebApplicationType.REACTIVE
  2. 如果项目依赖中不存在org.springframework.web.reactive.DispatcherHandler,也不存在org.springframework.web.servlet.DispatcherServlet,那么应用类型为WebApplicationType.NONE
  3. 否则,应用类型为WebApplicationType.SERVLET

获取BootstrapRegistryInitializer对象

  1. 从"META-INF/spring.factories"中读取key为BootstrapRegistryInitializer类型的扩展点,并实例化出对应扩展点对象
  2. BootstrapRegistryInitializer的作用是可以初始化BootstrapRegistry
    上面的DefaultBootstrapContext对象就是一个BootstrapRegistry,可以用来注册一些对象,这些对象可以用在3. 从SpringBoot启动到Spring容器初始化完成的过程中
  3. 我的理解:没有Spring容器之前就利用BootstrapRegistry来共享一些对象,有了Spring容器之后就利用Spring容器来共享一些对象

获取ApplicationContextInitializer对象

  1. 从"META-INF/spring.factories"中读取key为ApplicationContextInitializer类型的扩展点,并实例化出对应扩展点对象
  2. 顾名思义,ApplicationContextInitializer是用来初始化Spring容器ApplicationContext对象的,比如可以利用ApplicationContextInitializer来向Spring容器中添加ApplicationListener

获取ApplicationListener对象

  1. 从"META-INF/spring.factories"中读取key为ApplicationListener类型的扩展点,并实例化出对应扩展点对象
  2. ApplicationListener是Spring中的监听器,并不是SpringBoot中的新概念,不多解释了

推测出Main类(main()方法所在的类)

没什么具体的作用,逻辑是根据当前线程的调用栈来判断main()方法在哪个类,哪个类就是Main类

run(String… args)方法

  1. 创建DefaultBootstrapContext对象
  2. 利用BootstrapRegistryInitializer初始化DefaultBootstrapContext对象
  3. 获取SpringApplicationRunListeners
    这三个步骤没什么特殊的

触发SpringApplicationRunListener的starting()

默认情况下SpringBoot提供了一个EventPublishingRunListener,它实现了SpringApplicationRunListener接口,默认情况下会利用EventPublishingRunListener发布一个ApplicationContextInitializedEvent事件,程序员可以通过定义ApplicationListener来消费这个事件

创建Environment对象

Environment对象表示环境变量,该对象内部主要包含了:

  1. 当前操作系统的环境变量
  2. JVM的一些配置信息
  3. -D方式所配置的JVM环境变量

触发SpringApplicationRunListener的environmentPrepared()

默认情况下会利用EventPublishingRunListener发布一个ApplicationEnvironmentPreparedEvent事件,程序员可以通过定义ApplicationListener来消费这个事件,比如默认情况下会有一个EnvironmentPostProcessorApplicationListener来消费这个事件,而这个ApplicationListener接收到这个事件之后,就会解析application.properties、application.yml文件,并添加到Environment对象中去。

打印Banner

没什么特殊的

创建Spring容器对象(ApplicationContext)

会利用ApplicationContextFactory.DEFAULT,根据应用类型创建对应的Spring容器。
ApplicationContextFactory.DEFAULT为:

ApplicationContextFactory DEFAULT = (webApplicationType) -> {
    try {
        switch (webApplicationType) {
            case SERVLET:
                return new AnnotationConfigServletWebServerApplicationContext();
            case REACTIVE:
                return new AnnotationConfigReactiveWebServerApplicationContext();
            default:
                return new AnnotationConfigApplicationContext();
        }
    }
    catch (Exception ex) {
        throw new IllegalStateException("Unable create a default ApplicationContext instance, "
                                        + "you may need a custom ApplicationContextFactory", ex);
    }
};

所以:

  1. 应用类型为SERVLET,则对应AnnotationConfigServletWebServerApplicationContext
  2. 应用类型为REACTIVE,则对应AnnotationConfigReactiveWebServerApplicationContext
  3. 应用类型为普通类型,则对应AnnotationConfigApplicationContext

利用ApplicationContextInitializer初始化Spring容器对象

默认情况下SpringBoot提供了多个ApplicationContextInitializer,其中比较重要的有ConditionEvaluationReportLoggingListener,别看到它的名字叫XXXListener,但是它确实是实现了ApplicationContextInitializer接口的。

在它的initialize()方法中会:

  1. 将Spring容器赋值给它的applicationContext属性
  2. 并且往Spring容器中添加一个ConditionEvaluationReportListener(ConditionEvaluationReportLoggingListener的内部类),它是一个ApplicationListener
  3. 并生成一个ConditionEvaluationReport对象赋值给它的report属性

ConditionEvaluationReportListener会负责接收ContextRefreshedEvent事件,也就是Spring容器一旦启动完毕就会触发ContextRefreshedEvent,ConditionEvaluationReportListener就会打印自动配置类的条件评估报告。

触发SpringApplicationRunListener的contextPrepared()

默认情况下会利用EventPublishingRunListener发布一个ApplicationContextInitializedEvent事件,默认情况下暂时没有ApplicationListener消费了这个事件

调用DefaultBootstrapContext对象的close()

没什么特殊的,忽略

将启动类作为配置类注册到Spring容器中(load()方法)

将SpringApplication.run(MyApplication.class);中传入进来的类,比如MyApplication.class,作为Spring容器的配置类

触发SpringApplicationRunListener的contextLoaded()

默认情况下会利用EventPublishingRunListener发布一个ApplicationPreparedEvent事件

刷新Spring容器

调用Spring容器的refresh()方法,结合第9、13步,相当于执行了这样一个流程:

  1. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  2. applicationContext .register(MyApplication.class)
  3. applicationContext .refresh()

触发SpringApplicationRunListener的started()

发布ApplicationStartedEvent事件和AvailabilityChangeEvent事件,AvailabilityChangeEvent事件表示状态变更状态,变更后的状态为LivenessState.CORRECT

LivenessState枚举有两个值:

  1. CORRECT:表示当前应用正常运行中
  2. BROKEN:表示当前应用还在运行,但是内部出现问题,暂时还没发现哪里用到了

调用ApplicationRunner和CommandLineRunner

  1. 获取Spring容器中的ApplicationRunner类型的Bean
  2. 获取Spring容器中的CommandLineRunner类型的Bean
  3. 执行它们的run()

触发SpringApplicationRunListener的ready()

发布ApplicationReadyEvent事件和AvailabilityChangeEvent事件,AvailabilityChangeEvent事件表示状态变更状态,变更后的状态为ReadinessState.ACCEPTING_TRAFFIC

ReadinessState枚举有两个值:

  1. ACCEPTING_TRAFFIC:表示当前应用准备接收请求
  2. REFUSING_TRAFFIC:表示当前应用拒绝接收请求,比如Tomcat关闭时,就会发布AvailabilityChangeEvent事件,并且状态为REFUSING_TRAFFIC

上述过程抛异常了就触发SpringApplicationRunListener的failed()

发布ApplicationFailedEvent事件

配置文件解析

SpringBoot完整的配置优先级
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config

优先级由低到高(注意和我写的顺序是反的,我写的是由高到底)文章来源地址https://www.toymoban.com/news/detail-491327.html

  1. Default properties (specified by setting SpringApplication.setDefaultProperties).
  2. @PropertySource annotations on your @Configuration classes. Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.
  3. Config data (such as application.properties files).
  4. A RandomValuePropertySource that has properties only in random.*.
  5. OS environment variables.
  6. Java System properties (System.getProperties()).
  7. JNDI attributes from java:comp/env. 不管它
  8. ServletContext init parameters.
  9. ServletConfig init parameters.
  10. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
  11. Command line arguments.
  12. properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
  13. @TestPropertySource annotations on your tests.
  14. Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.

到了这里,关于SpringBoot启动过程探究及配置文件优先级解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • nacos配置文件优先级

    当前配置文件如下: 优先级:userservice-dev.yml(当前环境配置) userservice.yml(nacos上的) application.yml(本地的) 扩展配置(extension-configs) 共享配置(shared-configs) 同为扩展配置,存在如下优先级关系:extension-configs[3] extension-configs[2] extension-configs[1] extension-configs[0] 同为共享配置

    2024年02月12日
    浏览(30)
  • Nacos配置文件管理、微服务获取Nacos配置文件、热更新、配置共享、配置优先级等

    传统项目中,当我们需要修改配置文件时,需要修改配置文件,停掉服务,重启服务,这样不利于提升用户体验; 而使用Nacos进行项目的配置文件管理,则可以实现热更新配置文件,在Nacos中修改之后,Nacos会通知项目新的配置文件。 添加配置文件 第一步,点击添加配置:

    2023年04月11日
    浏览(31)
  • SpringCloud + Nacos配置文件加载顺序和优先级详解

    在微服务架构中,合理地管理和理解配置文件的加载顺序与优先级对于确保应用的稳定性和灵活性至关重要。特别是在使用 Spring Cloud Alibaba Nacos 作为配置中心的场景下,这一点显得尤为重要。本文将基于一个具体的 bootstrap.yml 配置示例,深入探讨这些概念,并介绍如何通过

    2024年03月27日
    浏览(40)
  • JavaWeb开发06-原理-Spring配置优先级-Bean管理-SpringBoot原理-Maven继承和聚合-私服

    不同配置文件,配置同一个属性谁有效 propertiesymlyaml 命令行参数Java系统属性 项目打包后要改变属性: 红色是Java系统属性,绿色是命令行参数 ‘ 获取IOC容器:applicationContext就是IOC容器对象 IOC容器中bean是默认单例的只有一个,这样三个获取的bean是同一个 单例还是多例取决

    2024年04月23日
    浏览(37)
  • 聊聊Spring Boot配置文件:优先级顺序、加载顺序、bootstrap.yml与application.yml区别详解

    在 Spring Boot 中,配置文件的优先级顺序是: application-{profile}.yml ( application-{profile}.properties ) application.yml ( application.properties ) bootstrap.yml ( bootstrap.properties )。其中, {profile} 表示不同的环境配置,如 dev 、 test 、 prod 等。 优先级从高到低,高优先级的配置覆盖低优先级

    2024年01月25日
    浏览(47)
  • SpringBoot中properties、yml、yaml的优先级

    配置优先级低的会先加载然后会被配置优先级高的覆盖 创建SpringBoot项目(网址)  在resource目录下创建application.properties、application.yml、application.yaml文件      运行     优先级顺序: propertiesymlyaml  

    2024年02月12日
    浏览(23)
  • Spring Boot 配置属性设置优先级

    文章首发地址 Spring Boot设计了非常特殊的加载指定属性文件(PropertySource)的顺序,以允许对属性值进行合理的覆盖。属性值会以下面的优先级进行设置。 home目录下的Devtools全局设置属性(~/.spring-boot-devtools.properties,条件是当devtools激活时)。 @TestPropertySource注解的测试用例

    2024年02月16日
    浏览(41)
  • Spring Boot的自动配置与自定义配置(附配置优先级表)

    相比于Spring MVC,Spring Boot省去了繁琐的配置,提供了大部分场景下的默认配置,用户可以在不做任何配置的情况下使用Spring Boot框架进行开发。如果默认的参数并不能满足用户的需求,也只需创建一个配置文件并加上自定义的配置。Spring Boot的主导思想,想必大家也并不陌生,

    2024年02月02日
    浏览(25)
  • Javaweb | 过滤器、配置、过滤器链、优先级

    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 概念 过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术 用户的请求和响应都需要经过过滤器 过滤器作用 执行地位在Servlet之前,客户端发送请求是,会先经过Filter,再到达目标Servlet中;响应时,会根

    2023年04月17日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包