SpringBoot外部化配置使用Plus版

PS: 之前写过一篇关于SpringBoo中使用配置文件的一些姿势,不过嘛,有句话(我)说的好:曾见小桥流水,未睹观音坐莲!所以再写一篇增强版,以便记录。

序言

上一篇博客记录,主要集中在具体的配置内容,也就是使用@ConfigurationProperties这个注解来进行配置与结构化对象的绑定,虽然也顺带说了下@Value的使用以及其区别。

在这篇记录中,打算从总览,鸟瞰的俯视视角,来从整体上对SpringBoot,乃至Spring Framework对于外部化配置文件处理,以及配置参数的绑定操作,是如果处理的、怎么设计的。

这里其实主要说的是 SpringBoot,虽然@Value属于Spring Framework的注解,不过在SpringBoot中也被频繁使用。

SpringBoot版本: 2.2.6.RELEASE

SpringBoot启动流程简介

在SpringBoot的启动过程中,大体上分为三步

第一步:prepareEnvironment,准备SpringBoot执行时所有的配置。

第二步:prepareContext,根据启动时的传入的配置类,创建其BeanDefinition。

第三步:refreshContext,真正启动上下文。

在这上面三步中,第一步结束后,我们所需要的或者配置文件配置的内容,大部分已经被加载进来,然后在第三步中进行配置的注入或者绑定操作。

至于为什么是大部分,后面会有解释。

将配置从配置文件加载到Environment中,使用的是事件通知的方式。

本篇博客记录仅仅聚焦第一步中如何读取配置文件的分析,顺带介绍下第三步的注入和绑定。

受限于技术水平,仅能达到这个程度

外部化配置方式

如果有看到SpringBoot官网关于外部化配置的说明,就会惊讶的发现,原来SpringBoot有那么多的配置来源。

SpringBoot关于外部化配置特性的文档说明,直达。

而实际使用中,通常可能会使用的比较多的是通过以下这些 方式

commandLine

通过在启动jar时,加上-DconfigKey=configValue或者 --configKey=configValue的方式,来进行配置,多个配置项用空格分隔。

这种使用场景也多,只是一般用于一些配置内容很少且比较关键的配置,比如说可以决定运行环境的配置。

不易进行比较多的或者配置内容比较冗长的配置,容易出错,且不便于维护管理。

application

这种是SpringBoot提供的,用于简便配置的一种方式,只要我们将应用程序所用到的配置,直接写到application.properties中,并将文件放置于以下四个位置即可 。

位于jar同目录的config目录下的application.properties

位于jar同目录的application.properties

classpath下的config内application.properties

classpath下的application.properties

以上配置文件类型也都可以使用yml

默认情况下,这种方式是SpringBoot约定好的一种方式,文件名必须为application,文件内容格式可以为Yaml或者Properties,也许支持XML,因为看源码是支持的,没有实践。

好处就是简单,省心省事,我们只需关注文件本身的内容就可,其他的无需关心,这也是 SpringBoot要追求的结果。

缺点也很明显,如果配置内容比较冗长,为了便于管理维护,增加可读性,必须要对配置文件进行切分,通过功能等维度进行分类分组,使用多个配置文件来进行存放配置数据。

SpringBoot也想到了这些问题,因此提供了下面两个比较方便的使用方式,来应对这种情况

profiles

profiles本身是也是一个配置项,它提供一种方式将部分应用程序配置进行隔离,并且使得它仅在具体某一个环境中可用。

具体实践中常用的主要是针对不同的环境,有开发环境用到的特有配置值,有测试环境特有的配置,有生产环境特有的配置,包括有些Bean根据环境选择决定是否进行实例化,这些都是通过profiles来实现的。不过这里只关注配置这一块内容。

它的使用方式通常是spring.profiles.active=dev,dev1或者 spring.profiles.include=db1,db2

这里可以看到有两种不同的用法,这两种方式是有区别的。

如果在application.properties中定义了一个spring.profiles.active=dev,而后在启动时通过 命令行又写了个 --spring.profiles.active=test,那么最终使用的是test,而不是dev。

如果同样的场景下,使用spring.profiles.include来替换spring.profiles.active,那么结果会是dev和test都会存在,而不是替换的行为 。

这就是两个之间的差别,这种差别也使得他们使用的场景并不一样,active更适合那些需要互斥的环境,而include则是多个并存的配置。

仅仅配置了profiles是没有意义的,必须要有相应的配置文件配合一起使用,而且这些配置文件的命名要符合一定的规则,否则配置文件不会被加载进Environment的。

profiles文件的命名规则为application-*.properties,同样的,application.properties能放置的位置它也可以,不能的,它也不可以。

propery source

注解@PropertySource可以写在配置类上,并且指定要读取的配置文件路径,这个路径可以是绝对路径,也可以是相对路径。

它可以有以下几种配置

@PropertySource("/config.properties")

@PropertySource("config.properties")

@PropertySource("file:/usr/local/config.properties")

@PropertySource("file:./config.properties")

@PropertySource("${pathPrefix}/config.properties")

其中1和2两种方式是一样的,都是从classpath去开始查找的

3和4是使用文件系统的绝对和相对路径的方式,这里绝对路径比较好理解 ,相对路径则是从项目的根目录作为相对目录的

5是结合SpEL的表达式来使用的,可以直接从环境中获取配置好的路径。

以上几种方式在实际开发中遇到和SpringBoot相关的配置,基本都能应付过来了。

不过对于上面配置的一些原理性的内容,还没有提到 ,下面会简单说一下SpringBoot关于配置更详细的处理,以及配置的优先级的问题。

原理浅入浅出

带着问题去找原因,比较有目的性和针对性,效果也相对好一些。

所以这里描述几个会引起疑问的现象

默认情况下自动加载的配置文件命名必须要是application

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyydyg.html