springboot创建并配置环境(二) - 配置基础环境

文章目录

一、介绍

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

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

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

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

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

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

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

  • MutablePropertySources

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

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

  • propertySources

    该属性指向MutablePropertySources对象。

  • propertyResolver

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

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

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

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

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

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

  • PropertiesPropertySource

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

  • SystemEnvironmentPropertySource

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

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

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

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

  • 系统属性

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

  • 系统环境变量

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

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

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

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

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

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

  • 设置类型转换器

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

  • 配置自定义的普通参数

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

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

    • 配置命令行参数

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

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

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

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

  • 配置来自命令行的profile

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

四、作为应用配置信息

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

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

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

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

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并没有把他们作为配置来看,如今它们成为了配置属性

点此进入上一集:springboot创建并配置环境(一) - 创建环境

点此进入下一集:springboot创建并配置环境(三) - 配置扩展属性(上集)

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

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

相关推荐
一只特立独行的猪6111 小时前
Java面试——集合篇
java·开发语言·面试
吃面不喝汤661 小时前
Flask + Swagger 完整指南:从安装到配置和注释
后端·python·flask
讓丄帝愛伱2 小时前
spring boot启动报错:so that it conforms to the canonical names requirements
java·spring boot·后端
weixin_586062022 小时前
Spring Boot 入门指南
java·spring boot·后端
雷袭月启2 小时前
SpringBoot实现OAuth客户端
spring boot·oauth客户端
Dola_Pan5 小时前
Linux文件IO(二)-文件操作使用详解
java·linux·服务器
wang_book5 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
蜗牛^^O^6 小时前
Docker和K8S
java·docker·kubernetes
从心归零6 小时前
sshj使用代理连接服务器
java·服务器·sshj
IT毕设梦工厂7 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计