<p>PS: 之前写过一篇关于 SpringBoo 中使用配置文件的一些姿势,不过嘛,有句话(我)说的好:曾见小桥流水,未睹观音坐莲!所以再写一篇增强版,以便记录。</p>
<p><span style="color: #ff0000"><strong>序言</strong></span><br>
</p>
<p>上一篇<a href="https://www.jb51.net/article/187405.htm" target="_blank">博客记录</a>,主要集中在具体的配置内容,也就是使用 @ConfigurationProperties 这个注解来进行配置与结构化对象的绑定,虽然也顺带说了下 @Value 的使用以及其区别。</p>
<p>在这篇记录中,打算从总览,鸟瞰的俯视视角,来从整体上对 SpringBoot ,乃至 Spring Framework 对于外部化配置文件处理,以及配置参数的绑定操作,是如果处理的、怎么设计的。</p>
<p>这里其实主要说的是 SpringBoot ,虽然 @Value 属于 Spring Framework 的注解,不过在 SpringBoot 中也被频繁使用。</p>
<p>SpringBoot 版本: 2.2.6.RELEASE</p>
<p><span style="color: #ff0000"><strong>SpringBoot启动流程简介<br>
</strong></span></p>
<p>在 SpringBoot 的启动过程中,大体上分为三步</p>
<p>第一步: prepareEnvironment ,准备 SpringBoot 执行时所有的配置。</p>
<p>第二步: prepareContext ,根据启动时的传入的配置类,创建其 BeanDefinition 。</p>
<p>第三步: refreshContext ,真正启动上下文。</p>
<p>在这上面三步中,第一步结束后,我们所需要的或者配置文件配置的内容,大部分已经被加载进来,然后在第三步中进行配置的注入或者绑定操作。</p>
<p>至于为什么是大部分,后面会有解释。</p>
<p>将配置从配置文件加载到Environment中,使用的是事件通知的方式。</p>
<p>本篇博客记录仅仅聚焦第一步中如何读取配置文件的分析,顺带介绍下第三步的注入和绑定。</p>
<p>受限于技术水平,仅能达到这个程度</p>
<p><span style="color: #ff0000"><strong>外部化配置方式</strong></span><br>
</p>
<p>如果有看到 SpringBoot 官网关于外部化配置的说明,就会惊讶的发现,原来 SpringBoot 有那么多的配置来源。</p>
<p>SpringBoot 关于外部化配置特性的文档说明,直达 <a href="https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/spring-boot-features.html#boot-features-external-config" target="_blank">地址</a> 。</p>
<p>而实际使用中,通常可能会使用的比较多的是通过以下这些 方式</p>
<p><strong>commandLine</strong><br>
</p>
<p>通过在启动jar时,加上 -DconfigKey=configValue 或者 --configKey=configValue 的方式,来进行配置,多个配置项用空格分隔。</p>
<p>这种使用场景也多,只是一般用于一些配置内容很少且比较关键的配置,比如说可以决定运行环境的配置。</p>
<p>不易进行比较多的或者配置内容比较冗长的配置,容易出错,且不便于维护管理。</p>
<p><strong>application</strong><br>
</p>
<p>这种是 SpringBoot 提供的,用于简便配置的一种方式,只要我们将应用程序所用到的配置,直接写到 application.properties 中,并将文件放置于以下四个位置即可 。</p>
<ol>
<li>位于 jar 同目录的 config 目录下的 application.properties</li>
<li>位于 jar 同目录的 application.properties</li>
<li>classpath 下的 config 内 application.properties</li>
<li>classpath 下的 application.properties</li>
</ol>
<p>以上配置文件类型也都可以使用yml</p>
<p>默认情况下,这种方式是 SpringBoot 约定好的一种方式,文件名必须为 application ,文件内容格式可以为 Yaml 或者 Properties ,也许支持 XML ,因为看源码是支持的,没有实践。</p>
<p>好处就是简单,省心省事,我们只需关注文件本身的内容就可,其他的无需关心,这也是 SpringBoot 要追求的结果。</p>
<p>缺点也很明显,如果配置内容比较冗长,为了便于管理维护,增加可读性,必须要对配置文件进行切分,通过功能等维度进行分类分组,使用多个配置文件来进行存放配置数据。</p>
<p>SpringBoot 也想到了这些问题,因此提供了下面两个比较方便的使用方式,来应对这种情况</p>
<p><span style="color: #000000"><strong>profiles</strong></span><br>
</p>
<p>profiles 本身是也是一个配置项,它提供一种方式将部分应用程序配置进行隔离,并且使得它仅在具体某一个环境中可用。</p>
<p>具体实践中常用的主要是针对不同的环境,有开发环境用到的特有配置值,有测试环境特有的配置,有生产环境特有的配置,包括有些 Bean 根据环境选择决定是否进行实例化,这些都是通过 profiles 来实现的。不过这里只关注配置这一块内容。</p>
<p>它的使用方式通常是 spring.profiles.active=dev,dev1 或者 spring.profiles.include=db1,db2</p>
<p>这里可以看到有两种不同的用法,这两种方式是有区别的。</p>
<p>如果在 application.properties 中定义了一个 spring.profiles.active=dev ,而后在启动时通过 命令行又写了个 --spring.profiles.active=test ,那么最终使用的是 test |
|