1. 程式人生 > >易筋SpringBoot2.1 | 第二篇:Spring Boot配置檔案詳解

易筋SpringBoot2.1 | 第二篇:Spring Boot配置檔案詳解

寫作時間:2018-12-22
Spring Boot: 2.1 ,JDK: 1.8, IDE: IntelliJ IDEA,

配置檔案說明

Spring Boot 配置檔案允許為同一套應用,為不同的環境用不同的配置檔案。比如開發環境、測試環境、生成環境。你可以用properties 檔案, YAML 檔案, 環境變數 , 和 命令列引數 去定製配置檔案. 屬性可以通過註解 @Value 注入內容,結構化物件可以通過註解 @ConfigurationProperties 注入內容。配置檔案英文關鍵詞: Externalized Configuration .

Spring Boot

配置檔案載入優先順序如下:

  1. Devtools全域性設定屬性在路徑 (~/.spring-boot-devtools.properties 當devtools啟用的時候).
  2. 測試用例上的 @TestPropertySource .
  3. 測試用例上的 @SpringBootTest#properties註解.
  4. 命令列引數.
  5. 配置在SPRING_APPLICATION_JSON 的屬性(環境變數或系統屬性中內嵌的內聯JSON).
  6. ServletConfig初始化引數.
  7. ServletContext 初始化引數.
  8. 配置在 java:comp/envJNDI
    (Java Naming and Directory Interface) 屬性.
  9. Java系統屬性 (System.getProperties()).
  10. 作業系統OS(Operating System)環境變數.
  11. RandomValuePropertySource 中的屬性只包括在包random.*.
  12. 沒有打進jar包的Profile-specific 應用屬性 (application-{profile}.properties 和 YAML ).
  13. 打進jar包中的Profile-specific 應用屬性 (application-{profile}.properties 和 YAML).
  14. 沒有打進jar包的應用配置 (application.properties 和 YAML).
  15. 打進jar包中的應用配置(application.properties 和 YAML).
  16. @Configuration類上的@PropertySource註解 .
  17. 預設屬性 (配置在檔案 SpringApplication.setDefaultProperties).

本章記錄最常用的配置檔案application.propertiesYAML

配置檔案位置讀取優先順序

application.properties 或者 application.yml 讀取優先順序如下:

  1. file:./config/當前位置的子目錄/config
  2. file:./當前位置
  3. classpath:/config/classpath /config 的包中
  4. classpath:/classpath的根目錄

Properties檔案中的佔位符

Placeholders佔位符,實際上是可以被後面的屬性運用的變數。
通過{佔位符}來替換掉裡面物件的內容。比如下面app.description=MyApp is a Spring Boot Application

app.name=MyApp
app.description=${app.name} is a Spring Boot application

用YAML代替 Properties

YAMLJSON的超集,可以分層來定義資料. SpringApplication 類自動支援 YAML 替換 propertiesclasspath載入了類庫SnakeYAML.
spring-boot-starter自動載入了類庫SnakeYAML

  1. YAML分層的例子:
environments:
	dev:
		url: http://dev.example.com
		name: Developer Setup
	prod:
		url: http://another.example.com
		name: My Cool App

等價於properties

environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App
  1. YAML配置list的例子,
my:
servers:
	- dev.example.com
	- another.example.com

等價於properties,陣列list帶了[index]

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

載入YAML

Spring Framework 提供了兩個方便的方法載入YAML檔案. YamlPropertiesFactoryBean 載入 YAML 當做 Properties,YamlMapFactoryBean 載入 YAML 當做a Map.

自定義屬性

參照教程【SpringBoot 2.1 | 第一篇:構建第一個SpringBoot工程】新建一個Spring Boot專案,名字叫democonfig, 在目錄src/main/java/resources 下找到配置檔案application.properties,重新命名為application.yml
定義屬性如下:

account:
  name: zgpeace
  age: 18
  number: ${random.int}
  uuid: ${random.uuid}
  max: ${random.int(10)}
  value: ${random.value}
  greeting: hi, I'm ${my.name}

其中配置檔案中用到了${random} ,它可以用來生成各種不同型別的隨機值。
讀取配置檔案裡面的內容,在屬性上用註解@Value("${屬性名}")
新建類com.zgpeace.democonfig.MineController.java, 實現如下:

package com.zgpeace.democonfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MineController {
    @Value("${account.name}")
    private String name;
    @Value("${account.age}")
    private int age;

    @RequestMapping(value = "/author")
    public String mine() {
        return name+ ": " + age;
    }
}

啟動應用,命令列訪問結果如下:

$ curl http://localhost:8080/author
zgpeace: 18

將配置檔案的屬性賦給實體類

配置檔案的欄位可以賦值給JavaBean, 結構化物件可以通過註解 @ConfigurationProperties 注入內容,建立類com.zgpeace.democonfig.bean.ConfigBean, 實現如下:

package com.zgpeace.democonfig.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "account")
@Component
public class ConfigBean {

    private String name;
    private int age;
    private int number;
    private String uuid;
    private int max;
    private String value;
    private String greeting;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getGreeting() {
        return greeting;
    }

    public void setGreeting(String greeting) {
        this.greeting = greeting;
    }
}

實現類com.zgpeace.democonfig.MineController修改為:

package com.zgpeace.democonfig;

import com.zgpeace.democonfig.bean.ConfigBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableConfigurationProperties({ConfigBean.class})
public class MineController {

    @Autowired
    ConfigBean configBean;

    @Value("${account.name}")
    private String name;
    @Value("${account.age}")
    private int age;

    @RequestMapping(value = "/author")
    public String mine() {
        return name+ ": " + age;
    }

    @RequestMapping(value = "/lucy")
    public String person() {
        return configBean.getGreeting() + " >>>" + configBean.getName() + " >>>" +configBean.getUuid() + " >>>" + configBean.getMax();
    }
}

啟動應用,在命令列訪問:

$ curl http://localhost:8080/lucy  
hi, I'm ${my.name} >>>zgpeace >>>86cc4c39-8715-46ef-9e9f-497a2c6fac22 >>>8

自定義配置檔案

上面介紹的檔案是放在properties.yml中,現在定義一個自己的檔案
specific.properties, 內容如下:

com.zgpeace.hobby=run marathon
com.zgpeace.fruit=orange

賦值給JavaBean,需要三個註解

  1. @Configuration
  2. @PropertySource(value = “classpath:specific.properties”)
  3. @ConfigurationProperties(prefix = “com.zgpeace”)
    新建類com.zgpeace.democonfig.bean.User,
package com.zgpeace.democonfig.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "classpath:specific.properties")
@ConfigurationProperties(prefix = "com.zgpeace")
public class User {

    private String hobby;
    private String fruit;

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public String getFruit() {
        return fruit;
    }

    public void setFruit(String fruit) {
        this.fruit = fruit;
    }
}

執行程式,在命令列測試:

$ curl http://localhost:8080/user
hobby: run marathon ; fruit: orange

多個環境配置檔案

除了application.properties 或者 application.yml外,可以自定義環境配置檔案的格式為application-{profile}.properties。環境有預設的定製配置檔案application-default.properties,預設會載入。但是使用者定製的檔案會覆蓋掉預設的檔案。
比如開發環境、測試環境、生成環境定義三個配置檔案

  1. application-test.properties:測試環境
server:
  port: 8082
  1. application-dev.properties:開發環境
server:
  port: 8086
  1. application-prod.properties:生產環境
server:
  port: 8088

Spring Profiles提供了一種隔離應用程式配置的方式,並讓這些配置只在特定的環境下生效。啟用方式為設定application.yml 中設定profile: active :

spring:
  profiles:
    active: dev

啟動應用,發現程式的埠不再是8080,而是8082。

程式碼地址

https://github.com/zgpeace/Spring-Boot2.1/tree/master/democonfig

參考

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
https://blog.csdn.net/forezp/article/details/70437576