springboot创建并配置环境2 - 配置基础环境

简介: springboot创建并配置环境2 - 配置基础环境

一、介绍

上一篇文章:springboot创建并配置环境1 - 创建环境 中我们探讨了springboot是如何根据当前应用程序类型去创建对应的环境实例的。接下来探讨如何去配置完善该运行环境。

本文基于以下版本进行展开:

  • jdk:1.8
  • springboot:2.4.3

另外:由于篇幅过长,决定分四集文章来讲解分析

一、创建环境

二、配置基础环境

三、配置扩展属性(上)

四、配置扩展属性(下)

下面我们以标准环境StandardEnvironment为例进行分析。

二、配置系统属性和环境变量

首先我们应该判断在创建一个运行环境实例对象时,在构造器内部是否就已经开始对某些配置属性进行处理了。

在创建运行环境实例时,是通过标准环境StandardEnvironment的无参构造方法完成的,进入该构造方法后发现它是一个空方法

标准运行环境无参构造方法.png

由于该类继承于AbstractEnvironment,那么在执行StandardEnvironment的构造方法时会默认先调用父类的无参构造方法,接下来再看父类的无参构造。

抽象环境的构造方法.png

在该无参构造中,先实例化一个MutablePropertySources对象,然后再调用了下面的有参构造方法,并对propertySourcespropertyResolver这两个属性进行初始化。

  • MutablePropertySources

    该类内部维护了一个PropertySource集合,该集合中保存着大量以key,value形式的属性配置,且value值可以是任何数据类型。mutable意为可变的,表示允许调用方去修改其内部的属性配置。如下图所示

    MutablePropertySources类.png

看到PropertiySource大家是否还有印象,我们在springboot从命令行读取应用程序参数这篇文章中有介绍过,它其实就是一个以key,value形式的属性配置对象,且value值可以是任何数据类型(用泛型T表示)。

  • propertySources

    该属性指向MutablePropertySources对象。

  • propertyResolver

    属性解析器,提供一些从propertySources中获取所需要的属性的方法。

该运行环境实例的两个重要属性初始化完成后,该实例就具备了利用属性解析器propertyResolver解析配置属性并将解析后的结果保存到propertySources中的功能了。

接下来我们再看customizePropertySources()方法做了什么?从命名上来看,它可以自定义地添加一些属性,查看该方法是一个空方法

抽象父类的customizePropertySources方法.png

那么我们再回到它的子类StandardEnvironment查看该方法实现。

标准环境的customizePropertySources方法.png

在该方法中,我们可以看到,通过调用MutablePropertySourcesaddLast()方法,向其内部的PropertySource集合尾部添加两种属性:PropertiesPropertySourceSystemEnvironmentPropertySource

这两个类都是PropertiySource抽象类的实现类,用于保存不同类型的属性,但他们本质上都是PropertiySource实例。其中

  • PropertiesPropertySource

    该类用于保存系统属性,其中key为systemPropertiesvalue为Map集合,该集合中保存所有系统属性

  • SystemEnvironmentPropertySource

    该类用于保存系统环境变量,其中key为systemEnvironmentvalue为Map集合,该集合中保存所有系统环境变量

另外,PropertiySource还有很多种不同的实现类,用于保存不同类型的属性,如下所示

PropertySource的各种实现.png

下面我们用图示将当前已经保存的属性、以及目前运行环境保存属性的结构表示出来

运行环境中保存的属性1.png

好了,说了这么多我会不会是在瞎说,我们测一下就好了,把断点打在创建标准环境StandardEnvironment实例的下一行,查看此时运行环境中的属性

创建环境实例后的属性.png

  • 系统属性

    从调试中我们看到,springboot找到了64个系统属性

    系统属性.png

  • 系统环境变量

    从调试中我们看到,springboot找到了65个系统环境变量

    环境变量.png

三、配置自定义属性命令行参数

自定义属性主要是来自命令行参数。在前面的文章springboot读取命令行参数中我们已经详细介绍过springboot是如何读取命令行参数并将其保存在ApplicationArguments对象中的,但这些来自命令行的参数目前并不能作为启动环境信息、,需要将其也保存到启动环境中。

我们继续读prepareEnvironment()方法源码,来到configureEnvironment()这一行,

prepareEnvironment()方法.png

进入configureEnvironment()方法,该方法的逻辑主要分三部分,其中第一部分设置类型转换器

configureEnvironment()方法.png

该方法的处理逻辑主要分三部分

  • 设置类型转换器

    该部分逻辑只是向环境中设置一些springboot内置的类型转换器Convertor,本篇文章不具体展开来讲。

  • 配置自定义的普通参数

    configurePropertySources方法.png

  • 首先将默认属性配置添加到MutablePropertySources的尾部

    默认属性配置的设置方法是通过SpringApplication对象的setDefaultProperties()方法设置的,如下所示

    设置defaultProperties的方法.png

  • 配置命令行参数

    在前面的文章springboot读取命令行参数我们已经详细介绍过springboot如何将命令行参数转为SimpleCommandLinePropertySource,本文就不再赘述。

    在这一步会先判断我们已经保存的属性配置中是否已经存在key=commandLineArgs了,从我们逐行阅读源码的过程中我们可以断定是不存在这样的属性的,因此会执行else代码块,即只需要将SimpleCommandLinePropertySource添加到已经保存的属性配置的首部即可。

    此时我们再次用图示将当前已经保存的属性、以及目前运行环境保存属性的结构表示出来

    运行环境中保存的属性2.png

当然了,如果你想拒绝任何来自命令行的属性参数,可以通过以下方法将`addCommandLineProperties`属性设置为`false`,这样springboo就不会把命令行参数保存到启动环境中了

![关闭命令行参数功能.png](https://ucc.alicdn.com/pic/developer-ecology/een7m2naevh4a_16e76d38a560490c870332b9c03e53d9.png)
  • 配置来自命令行的profile

    该方法为空方法,保留该方法方面日后扩展。

    configureProfiles()方法.png

四、作为应用配置信息

在处理完自定义的属性后,下一步springboot需要对当前启动环境中的属性配置适配ConfigurationPropertySources的支持,如下图所示

添加ConfigurationPropertySources的支持.png

进入attach()方法,如下所示

attach()方法.png

该方法执行后的结果就是将当前启动环境中已保存的属性配置source封装到一个ConfigurationPropertySourcesPropertySource对象中,并且对应的key=configurationProperties,此时启动环境中保存的属性配置如下所示

运行环境中保存的属性3.png

至于为什么这么做,我们可以看一下方法注释:

Attach a ConfigurationPropertySource support to the specified Environment. Adapts each PropertySource managed by the environment to a ConfigurationPropertySource and allows classic PropertySourcesPropertyResolver calls to resolve using configuration property names.
The attached resolver will dynamically track any additions or removals from the underlying Environment property sources.

从注释中得知,该方法的目的就是真正的把当前保存在启动环境中的这些propertySources作为配置属性,就是说这些属性在此之前springboot并没有把他们作为配置来看,如今它们成为了配置属性

点此进入上一集:创建环境

点此进入下一集:配置扩展属性(上)




纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

相关文章
|
5月前
|
Arthas Java 测试技术
Docker 环境中 Spring Boot 应用的 Arthas 故障排查与性能优化实战
Docker 环境中 Spring Boot 应用的 Arthas 故障排查与性能优化实战
|
8月前
|
Java Linux Maven
SpringBoot多环境的yml或properties配置,生产环境和开发环境分离(超详细)
SpringBoot多环境的yml或properties配置,生产环境和开发环境分离(超详细)
135 0
|
2月前
|
XML 设计模式 Java
springboot创建并配置环境3 - 配置扩展属性(下)
springboot创建并配置环境3 - 配置扩展属性(下)
springboot创建并配置环境3 - 配置扩展属性(下)
|
2月前
|
XML JSON Java
springboot如何创建并配置环境3 - 配置扩展属性(上)
springboot如何创建并配置环境3 - 配置扩展属性(上)
springboot如何创建并配置环境3 - 配置扩展属性(上)
|
2月前
|
Java API uml
springboot创建并配置环境1 - 创建环境
springboot创建并配置环境1 - 创建环境
springboot创建并配置环境1 - 创建环境
|
2月前
|
XML 设计模式 Java
springboot如何创建并配置环境
springboot如何创建并配置环境
springboot如何创建并配置环境
|
3月前
|
Java Docker 容器
docker-compose部署一个springboot项目(包含环境)
docker-compose部署一个springboot项目(包含环境)
59 0
|
4月前
|
Java 数据处理 调度
论如何让Spring Boot在高压力环境下依然与众不同
论如何让Spring Boot在高压力环境下依然与众不同
|
5月前
|
Java 调度 Docker
Docker【应用 01】Spring Boot 项目部署在Linux环境下的Docker容器内举例(任务调度系统 xxl-job 任务调度中心)(手动版)
Docker【应用 01】Spring Boot 项目部署在Linux环境下的Docker容器内举例(任务调度系统 xxl-job 任务调度中心)(手动版)
80 0
|
5月前
|
Java 测试技术 Maven
【SpringBoot】多环境开发、分组管理、开发控制
【SpringBoot】多环境开发、分组管理、开发控制
23 0