Spring Boot 配置文件 – 在坑中實踐

摘要: 原創出處 www.bysocket.com 「泥瓦匠BYSocket 」歡迎轉載,保留摘要,謝謝!

『?倉廩實而知禮節,衣食足而知榮辱 -?管仲 』

本文提綱

一、自動配置

二、自定義屬性

三、random.* 屬性

四、多環境配置

運行環境:JDK 7 或 8,Maven 3.0+

技術棧:SpringBoot 1.5+

一、自動配置

Spring Boot 提供了對應用進行自動化配置。相比以前 XML 配置方式,很多顯式方式申明是不需要的。二者,大多數默認的配置足夠實現開發功能,從而更快速開發。

什么是自動配置

Spring Boot 提供了默認的配置,如默認的 Bean ,去運行 Spring 應用。它是非侵入式的,只提供一個默認實現。

大多數情況下,自動配置的 Bean 滿足了現有的業務場景,不需要去覆蓋。但如果自動配置做的不夠好,需要覆蓋配置。比如通過命令行動態指定某個 jar ,按不同環境啟動(這個例子在第 4 小節介紹)。那怎么辦?這里先要考慮到配置的優先級。

Spring Boot 不單單從?application.properties 獲取配置,所以我們可以在程序中多種設置配置屬性。按照以下列表的優先級排列:

1.命令行參數

2.java:comp/env 里的 JNDI 屬性

3.JVM 系統屬性

4.操作系統環境變量

5.RandomValuePropertySource 屬性類生成的 random.* 屬性

6.應用以外的?application.properties(或 yml)文件

7.打包在應用內的?application.properties(或 yml)文件

8.在應用 @Configuration 配置類中,用 @PropertySource 注解聲明的屬性文件

9.SpringApplication.setDefaultProperties 聲明的默認屬性

可見,命令好參數優先級最高。這個可以根據這個優先級,可以在測試或生產環境中快速地修改配置參數值,而不需要重新打包和部署應用。

還有第 6 點,根據這個在多 moudle 的項目中,比如常見的項目分 api 、service、dao 等 moudles,往往會加一個 deploy moudle 去打包該業務各個子 moudle,應用以外的配置優先。

二、自定義屬性

泥瓦匠喜歡按著代碼工程來講解知識。git clone 下載工程?springboot-learning-example ,項目地址見 GitHub -https://github.com/JeffLi1993/springboot-learning-example

a. 編譯工程

在項目根目錄 springboot-learning-example,運行 maven 指令:

cd?springboot-learning-example

mvn clean install

b. 運行工程 test 方法

運行?springboot-properties 工程?org.spring.springboot.property.PropertiesTest 測試類的 getHomeProperties 方法。可以在控制臺看到輸出,這是通過自定義屬性獲取的值:

HomeProperties{province='ZheJiang', city='WenLing', desc='dev: I'm living in ZheJiang WenLing.'}

怎么定義自定義屬性呢?

首先項目結構如下:

├── pom.xml

└── src

├── main

│?? ├── java

│?? │?? └── org

│?? │??? ? ?└── spring

│?? │??? ? ? ? ?└── springboot

│?? │??? ? ? ? ? ? ?├── Application.java

│?? │??? ? ? ? ? ? ?└── property

│?? │??? ? ? ? ? ? ? ? ?├── HomeProperties.java

│?? │??? ? ? ? ? ? ? ? ?└── UserProperties.java

│?? └── resources

│??? ? ?├── application-dev.properties

│??? ? ?├── application-prod.properties

│??? ? ?└── application.properties

└── test

├── java

│?? └── org

│??? ? ?└── spring

│??? ? ? ? ?└── springboot

│??? ? ? ? ? ? ?└── property

│??? ? ? ? ? ? ? ? ?├── HomeProperties1.java

│??? ? ? ? ? ? ? ? ?└── PropertiesTest.java

└── resouorces

└── application.yml

在 application.properties 中對應?HomeProperties 對象字段編寫屬性的 KV 值:

## 家鄉屬性 Dev

home.province=ZheJiang

home.city=WenLing

home.desc=dev: I'm living in ${home.province} ${home.city}.

這里也可以通過占位符,進行屬性之間的引用。

然后,編寫對應的?HomeProperties Java 對象:

/**

* 家鄉屬性

*

* Created by bysocket on 17/04/2017.

*/

@Component

@ConfigurationProperties(prefix = "home")

public class HomeProperties {

/**

* 省份

*/

private String province;

/**

* 城市

*/

private String city;

/**

* 描述

*/

private String desc;

public String getProvince() {

return province;

}

public void setProvince(String province) {

this.province = province;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

public String getDesc() {

return desc;

}

public void setDesc(String desc) {

this.desc = desc;

}

@Override

public String toString() {

return "HomeProperties{" +

"province='" + province + '\'' +

", city='" + city + '\'' +

", desc='" + desc + '\'' +

'}';

}

}

通過?@ConfigurationProperties(prefix = "home”) 注解,將配置文件中以 home 前綴的屬性值自動綁定到對應的字段中。同是用?@Component 作為 Bean 注入到 Spring 容器中。

如果不是用 application.properties 文件,而是用 application.yml 的文件,對應配置如下:

## 家鄉屬性

home:

province: 浙江省

city: 溫嶺松門

desc: 我家住在${home.province}的${home.city}

鍵值對冒號后面,必須空一格。

注意這里,就有一個坑了:

application.properties 配置中文值的時候,讀取出來的屬性值會出現亂碼問題。但是?application.yml 不會出現亂碼問題。原因是,Spring Boot 是以?iso-8859 的編碼方式讀取?application.properties 配置文件。

注意這里,還有一個坑:

如果定義一個鍵值對user.name=xxx,這里會讀取不到對應寫的屬性值。為什么呢?Spring Boot 的默認 StandardEnvironment 首先將會加載?“systemEnvironment"?作為首個PropertySource. 而 source 即為System.getProperties().當 getProperty時,按照讀取順序,返回 “systemEnvironment"?的值.即 System.getProperty("user.name")

(Mac 機子會讀自己的登錄賬號,這里感謝我的死黨http://rapharino.com/

三、random.* 屬性

Spring Boot 通過?RandomValuePropertySource 提供了很多關于隨機數的工具類。概括可以生成隨機字符串、隨機 int 、隨機 long、某范圍的隨機數。

運行?springboot-properties 工程?org.spring.springboot.property.PropertiesTest 測試類的?randomTestUser 方法。多次運行,可以發現每次輸出不同 User 屬性值:

UserProperties{id=-3135706105861091890, age=41, desc='泥瓦匠叫做3cf8fb2507f64e361f62700bcbd17770', uuid='582bcc01-bb7f-41db-94d5-c22aae186cb4'}

application.yml 方式的配置如下(?application.properties 形式這里不寫了):

## 隨機屬性

user:

id: ${random.long}

age: ${random.int[1,200]}

desc: 泥瓦匠叫做${random.value}

uuid: ${random.uuid}

四、多環境配置

很多場景的配置,比如數據庫配置、Redis 配置、注冊中心和日志配置等。在不同的環境,我們需要不同的包去運行項目。所以看項目結構,有兩個環境的配置:

application-dev.properties:開發環境

application-prod.properties:生產環境

Spring Boot 是通過 application.properties 文件中,設置 spring.profiles.active 屬性,比如 ,配置了 dev ,則加載的是?application-dev.properties :

# Spring Profiles Active

spring.profiles.active=dev

那運行?springboot-properties 工程中?Application 應用啟動類,從控制臺中可以看出,是加載了 application-dev.properties 的屬性輸出:

HomeProperties{province='ZheJiang', city='WenLing', desc='dev: I'm living in ZheJiang WenLing.'}

將?spring.profiles.active 設置成 prod,重新運行,可得到 application-prod.properties的屬性輸出:

HomeProperties{province='ZheJiang', city='WenLing', desc='prod: I'm living in ZheJiang WenLing.'}

根據優先級,順便介紹下 jar 運行的方式,通過設置 -Dspring.profiles.active=prod 去指定相應的配置:

mvn package

java -jar?-Dspring.profiles.active=prod springboot-properties-0.0.1-SNAPSHOT.jar

五、小結

常用的樣板配置在 Spring Boot 官方文檔給出,我們常在?application.properties(或 yml)去配置各種常用配置:

http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

感謝資料:

http://blog.didispace.com/springbootproperties/

https://docs.spring.io/spring-boot/docs

歡迎掃一掃我的公眾號關注 — 及時得到博客訂閱哦!

http://www.bysocket.com/

https://github.com/JeffLi1993

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容