• SpringBoot 源码 | prepareEnvironment 方法解析


    SpringBoot

    在 SpringBoot 启动流程中,主要的两个阶段是初始化 SpringApplication 对象以及 SpringApplication.run 方法执行的内容,今天主要细讲的是 SpringApplication.run 中的准备环境的 prepareEnvironment 方法源码 ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments)。prepareEnvironment 的源码如下

    prepareEnvironment 源码

    prepareEnvironment 主要包含方法 getOrCreateEnvironment、configureEnvironment、ConfigurationPropertySources.attach、DefaultPropertiesPropertySource.moveToEnd、bindToSpringApplication,

    这里我们先来为每行代码加上对应的注释

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {    // 创建和配置环境    ConfigurableEnvironment environment = getOrCreateEnvironment();    //配置 property sources 和 profiles    configureEnvironment(environment, applicationArguments.getSourceArgs());    //environment.getPropertySources()放在第一个位置    ConfigurationPropertySources.attach(environment);    //运行监听器通知所有监听器环境准备完成    listeners.environmentPrepared(bootstrapContext, environment);    //Move the 'defaultProperties' property source so that it's the last source    DefaultPropertiesPropertySource.moveToEnd(environment);    Assert.state(!environment.containsProperty("spring.main.environment-prefix"),            "Environment prefix cannot be set via properties.");    //Bind the environment to the {@link SpringApplication}    bindToSpringApplication(environment);    //环境转换成StandardEnvironment    if (!this.isCustomEnvironment) {        environment = convertEnvironment(environment);    }    ConfigurationPropertySources.attach(environment);    //返回环境配置对象ConfigurableEnvironment    return environment;}

    复制代码

    首先来看方法 getOrCreateEnvironment

    getOrCreateEnvironment

    官方注释 Create and configure the environment 创建和配置环境,由于我们的是 SERVLET 类型,所以这里会返回 ApplicationServletEnvironment 对象

    configureEnvironment

    继续往下执行看到 configureEnvironment 方法,configureEnvironment 方法主要是配置 property sources or profiles,源码可以看到

    configurePropertySources

    继续跟进 configurePropertySources 方法可以看到官方注释 Add, remove or re-order any {@link PropertySource}s in this application's environment 意为在此应用程序环境中添加、删除或重新排序任何{@link PropertySource},源码如下

    其中方法 environment.getPropertySources()主要是为了获取 ApplicationServletEnvironment 中的 PropertySources,获取之后会判断 Map defaultProperties;是否不为 null,不为 null 则执行 addOrMerge 判断是需要新增或者合并 DefaultPropertiesPropertySource

    回到 configurePropertySources 方法向下执行,

    这里的 args 是 the application arguments (usually passed from a Java main method)从 run 方法带下来的参数,这里判断 args 的长度是否大于 0,满足条件后判断当前 sources 中是否包含命令行参数,包含的话就需要用 args 中参数替换 sources 中对应 name 的参数,如果不包含则直接把 args 放在首位,

    configureProfiles

    我们再来看 configureProfiles 方法,可以看到

    官方注释 Configure which profiles are active (or active by default) for this application environment. Additional profiles may be activated during configuration file processing via the {@code spring.profiles.active} property.的意思也就是说在配置文件处理过程中,可以通过{@code-spring.profiles.active}属性激活其他配置文件。

    具体的实现去查看 ConfigFileApplicationListener 类 By default properties will be loaded from

    'application.properties' and/or 'application.yml' files in the following locations 属性内容会从 application.properties 或者 application.yml 加载,继续向下执行

    ConfigurationPropertySources.attach

    ConfigurationPropertySources.attach 方法

    主要是为了将 ConfigurationPropertySource 附加到指定 Environment,遍历 Environment 管理的每个 PropertySource 到 ConfigurationPropertySource 同时允许 PropertySourcesPropertyResolver 调用使用 ConfigurationPropertyName 配置的属性名,同时放在首位,之后 listeners.environmentPrepared 完成环境准备

    DefaultPropertiesPropertySource.moveToEnd

    之后调用 DefaultPropertiesPropertySource.moveToEnd 将 Move the 'defaultProperties' property source so that it's the last source 移动到 source 末尾

    bindToSpringApplication

    环境参数配置完成之后执行 bindToSpringApplication 将环境配置参数绑定到 SpringApplication

    convertEnvironment

    如果 isCustomEnvironment 为 false 则将 ConfigurableEnvironment 转换为 application environment 并且不直接解析配置文件属性的应用程序环境

    最后再执行一次 ConfigurationPropertySources.attach,完成之后返回环境配置对象 ConfigurableEnvironment,至此 prepareEnvironment 方法执行完成。

    总结

    执行完成准备环境的 prepareEnvironment 方法之后,会继续执行容器上下文启动前的其他准备工作,后续我会继续更新,欢迎共同讨论,一同进步。

  • 相关阅读:
    ​软考-高级-系统架构设计师教程(清华第2版)【第4章 信息安全技术基础知识(P160~189)-思维导图】​
    创建 MQTT 连接时如何设置参数?
    [黑马程序员Pandas教程]——DataFrame查询数据
    【红外图像】利用红外图像处理技术对不同制冷剂充装的制冷系统进行性能评估(Matlab代码实现)
    10天学完React——03、组件之间的props通信
    ARM内核地址对齐访问如何理解
    用好单例设计模式,代码性能提升300%
    【基础】什么是视锥体
    详解c++STL—STL常用算法
    【STM32】【HAL库】【实用制作】数控收音机(硬件设计)
  • 原文地址:https://blog.csdn.net/AS011x/article/details/126813558