• 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 方法之后,会继续执行容器上下文启动前的其他准备工作,后续我会继续更新,欢迎共同讨论,一同进步。

  • 相关阅读:
    JavaScript的学习之强制类型转换
    银行软件测试:基于互联网金融平台的测试框架设计与分析
    软件设计不是CRUD(24):系统耦合性变化对性能的影响以及优化措施
    相等全等运算符
    谈谈多线程与多线程同步
    Ruoyi集成flyway后启动报错的解决方法
    Java Int与Integer的区别
    内存 地址转换、分段、空闲空间管理
    Win10系统打开组策略编辑器的两种方法
    线程的“结束”
  • 原文地址:https://blog.csdn.net/AS011x/article/details/126813558