SpringBoot基礎篇配置信息之多環境配置信息

更多Spring文章,歡迎點擊 一灰灰Blog-Spring專題java

前面一篇主要介紹的是如何獲取配置信息,接下來則是另一個很是很是基礎和必要的知識點了,應用如何根據不一樣的環境來選擇對應的配置,即配置的多環境選擇問題git

<!-- more -->github

I. 多環境配置

配置區分環境,最直觀的如測試環境和生產環境的DB不一樣,測試環境的應用要求鏈接測試DB;生成環境的應用要求連生成DB;對於應用自己來講,業務代碼啥的都是同樣,無非就是DB的配置不一樣,若是在代碼中寫死環境判斷,而後進行選擇配置話,就不太優雅了;spring

SpringBoot自己就支持多環境配置文件,應用的配置,除了 application.yml 文件以外,還會有環境相關的配置,以下一個實例app

application.yml
application-dev.yml
application-pro.yml

1. 多環境選擇

a. 命令規則

配置文件,通常要求是以 application 開頭,能夠是yml文件也能夠是properties文件dom

b. 配置選擇

如何肯定哪一個配置配置文件(application-dev.yml 與 application-pro.yml)生效呢?spring-boot

  • 經過配置信息 spring.profile.active 來指定須要加載的配置文件

一般這個配置信息會放在 applicatin.yml 文件中,以下工具

spring:
  profiles:
    active: dev

上面這個表示,當前的配置信息,會從 application.ymlapplication-dev.yml 文件中獲取;且-dev文件中定義的配置信息,會覆蓋前面的配置信息學習

注意開發工具

  • 上面這個配置的value,能夠指定多個配置文件,用英文逗號分隔
  • 其中最右邊的優先級最高,覆蓋左邊配置文件中重名的配置信息

c. 實例演示

配置文件內容以下

application.yml

# 端口號
server:
  port: 8081

spring:
  profiles:
    active: dev,biz


biz:
  total: application

application-dev.yml

biz:
  env: dev-environment
  profile: dev-profile

application-pro.yml

biz:
  env: pro-environment
  profile: pro-profile

application-biz.yml

biz:
  whitelist: a,b,c,d,e,f,g
  ratelimit: 1,2,3
  total: application-biz
  profile: biz-profile

經過前面的規則進行分析,當前選中生效的配置文件爲

  • application.yml, application-dev.yml, application-biz.yml
  • 優先級爲:biz文件的配置覆蓋dev文件,dev文件的覆蓋application的配置

代碼驗證以下

package com.git.hui.boot.properties;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;

/**
 * Created by @author yihui in 09:17 18/9/20.
 */
@SpringBootApplication
public class Application {

    public Application(Environment environment) {
        String env = environment.getProperty("biz.env");

        String whitelist = environment.getProperty("biz.whitelist");
        String ratelimit = environment.getProperty("biz.ratelimit");

        String total = environment.getProperty("biz.total");
        String profile = environment.getProperty("biz.profile");

        // application.yml文件中的配置 spring.profile.active指定具體選中的配置文件,爲 application-dev 和 application-biz
        // read from application-dev.yml
        System.out.println("env: " + env);

        // read from application-biz.yml
        System.out.println("whitelist: " + whitelist);
        System.out.println("ratelimit: " + ratelimit);


        // 當配置文件 application.yml, application-dev.yml, application-biz.yml 三個文件都存在時,覆蓋規則爲
        // biz > dev > application.yml  (其中 biz>dev的原則是根據 spring.profile.active 中定義的順序來的,最右邊的優先級最高)
        // read from application-biz.yml
        System.out.println("total: " + total);

        // read from application-biz.yml
        System.out.println("profile: " + profile);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

}

輸出結果爲

env: dev-environment
whitelist: a,b,c,d,e,f,g
ratelimit: 1,2,3
total: application-biz
profile: biz-profile

2. 優先級問題

上面雖然看是實現了多環境的配置問題,但看完以後有一個明顯的疑問,選擇環境的配置信息寫死在application.yml文件中,難道說部署到測試和生產環境時,還得記得手動改這個配置的值麼?

若是是這樣的話,也太容易出問題了吧。。。

那麼如何解決這個問題呢,常見的一種方式是經過啓動腳本,傳入當前環境的參數,來覆蓋選中的環境

a. 配置文件優先級

默認的配置文件是放在 src/main/resources 目錄下,固然也是能夠放其餘位置的

  • 外置,在相對於應用程序運行目錄的 /config 子目錄中
  • 外置,在應用程序運行的目錄中
  • 內置,放在config包下(即 src/main/resources/config)目錄下
  • 內置,放在classpath根目錄下(即默認的 src/main/resources/目錄下)

上面的優先級是從高到低來的,即外置的改與內置的;config下面的高於根目錄下的

之內置的兩個進行對比,實測結果以下

優先級對比測試

b. 配置信息來源

前面一篇中,遺留了一個問題,就是在配置文件中配置了屬性 user.name = 一灰灰blog, 可是實際取出的倒是 user (我我的的電腦用戶名),也就是說,Environment中讀取的配置信息,不只僅是從配置文件中獲取,還要其餘的一些配置信息來源

根據優先級對屬性來源進行排序,以下

  • 根目錄下的開發工具全局設置屬性(當開發工具激活時爲~/.spring-boot-devtools.properties)。
  • 測試中的@TestPropertySource註解。
  • 測試中的@SpringBootTest#properties註解特性。
  • 命令行參數
  • SPRING_APPLICATION_JSON中的屬性(環境變量或系統屬性中的內聯JSON嵌入)。
  • ServletConfig初始化參數。
  • ServletContext初始化參數。
  • java:comp/env裏的JNDI屬性
  • JVM系統屬性
  • 操做系統環境變量
  • 隨機生成的帶random.* 前綴的屬性(在設置其餘屬性時,能夠應用他們,好比${random.long})
  • 應用程序之外的application.properties或者appliaction.yml文件
  • 打包在應用程序內的application.properties或者appliaction.yml文件
  • 經過@PropertySource標註的屬性源
  • 默認屬性(經過SpringApplication.setDefaultProperties指定).

3. 環境選擇的幾種方式

看了上面的配置信息來源,咱們能夠如何優雅的實現不一樣環境選擇不一樣的配置文件呢?有下面兩個容易想到和實現的方式了

  • 命令行參數
  • 應用程序外的配置文件

a. 命令行參數方式

這種實現思路就是在啓動腳本中,傳入當前環境,而後覆蓋掉屬性 --spring.profiles.active,對業務來講,就不須要作任何的改動了,只要啓動腳本自己區分環境便可,惟一的要求就是遵循統一的規範,一個簡單的實現以下

假定命令行的第一個參數就是環境,取出這個參數,傳入便可

public static void main(String[] args) {
      if (args.length > 0) {
          SpringApplication.run(Application.class, "--spring.profiles.active=" + args[0] + ",biz");
      } else {
          SpringApplication.run(Application.class);
      }
  }

實測結果,注意下面紅框內的pro,覆蓋了配置文件中的dev

配置覆蓋測試

說明

固然能夠直接傳入完整的命令行參數--spring.profiles.active=pro,biz,這樣代碼內部就不須要進行特殊處理

b. 外置配置文件方式

當程序以獨立的jar運行時,我我的的感受是外置的配置文件是優於內置的配置文件的;由於修改配置的話,不須要從新打包部署,直接改便可

這種實現方式也沒啥好多說的,至關於把配置文件拉出來放在外面而已,再根據環境寫具體的spring.profiles.active的值

II. 小結

  1. SpringBoot是支持多環境的配置,經過配置屬性 spring.profiles.active 來指定
  2. spring.profiles.active參數指定多個配置文件時,右邊的優於左邊的
  3. 應用外的配置文件優先於應用內,config目錄下的優先於根目錄下的
  4. 配置參數來源及優先級能夠參看前文: 配置信息來源
  5. 命令行參數傳入時,請注意寫法形同 --key=value

III. 其餘

0. 項目

1. 一灰灰Blog

一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛

2. 聲明

盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

3. 掃描關注

一灰灰blog

QrCode

知識星球

goals

相關文章
相關標籤/搜索