是時候搞清楚 Spring Boot 的配置檔案 application.properties 了!

江南一點雨發表於2019-05-30

在 Spring Boot 中,配置檔案有兩種不同的格式,一個是 properties ,另一個是 yaml 。

雖然 properties 檔案比較常見,但是相對於 properties 而言,yaml 更加簡潔明瞭,而且使用的場景也更多,很多開源專案都是使用 yaml 進行配置(例如 Hexo)。除了簡潔,yaml 還有另外一個特點,就是 yaml 中的資料是有序的,properties 中的資料是無序的,在一些需要路徑匹配的配置中,順序就顯得尤為重要(例如我們在 Spring Cloud Zuul 中的配置),此時我們一般採用 yaml。關於 yaml ,鬆哥之前寫過一篇文章:Spring Boot 中的 yaml 配置簡介

本文主要來看看 properties 的問題。

位置問題

首先,當我們建立一個 Spring Boot 工程時,預設 resources 目錄下就有一個 application.properties 檔案,可以在 application.properties 檔案中進行專案配置,但是這個檔案並非唯一的配置檔案,在 Spring Boot 中,一共有 4 個地方可以存放 application.properties 檔案。

  1. 當前專案根目錄下的 config 目錄下
  2. 當前專案的根目錄下
  3. resources 目錄下的 config 目錄下
  4. resources 目錄下

按如上順序,四個配置檔案的優先順序依次降低。如下:

是時候搞清楚 Spring Boot 的配置檔案 application.properties 了!

這四個位置是預設位置,即 Spring Boot 啟動,預設會從這四個位置按順序去查詢相關屬性並載入。但是,這也不是絕對的,我們也可以在專案啟動時自定義配置檔案位置。

例如,現在在 resources 目錄下建立一個 javaboy 目錄,目錄中存放一個 application.properties 檔案,那麼正常情況下,當我們啟動 Spring Boot 專案時,這個配置檔案是不會被自動載入的。我們可以通過 spring.config.location 屬性來手動的指定配置檔案位置,指定完成後,系統就會自動去指定目錄下查詢 application.properties 檔案。

是時候搞清楚 Spring Boot 的配置檔案 application.properties 了!

此時啟動專案,就會發現,專案以 classpath:/javaboy/application.propertie 配置檔案啟動。

這是在開發工具中配置了啟動位置,如果專案已經打包成 jar ,在啟動命令中加入位置引數即可:

java -jar properties-0.0.1-SNAPSHOT.jar --spring.config.location=classpath:/javaboy/

檔名問題

對於 application.properties 而言,它不一定非要叫 application ,但是專案預設是去載入名為 application 的配置檔案,如果我們的配置檔案不叫 application ,也是可以的,但是,需要明確指定配置檔案的檔名。

方式和指定路徑一致,只不過此時的 key 是 spring.config.name 。

首先我們在 resources 目錄下建立一個 app.properties 檔案,然後在 IDEA 中指定配置檔案的檔名:

是時候搞清楚 Spring Boot 的配置檔案 application.properties 了!

指定完配置檔名之後,再次啟動專案,此時系統會自動去預設的四個位置下面分別查詢名為 app.properties 的配置檔案。當然,允許自定義檔名的配置檔案不放在四個預設位置,而是放在自定義目錄下,此時就需要明確指定 spring.config.location 。

配置檔案位置和檔名稱可以同時自定義。

普通的屬性注入

由於 Spring Boot 源自 Spring ,所以 Spring 中存在的屬性注入,在 Spring Boot 中一樣也存在。由於 Spring Boot 中,預設會自動載入 application.properties 檔案,所以簡單的屬性注入可以直接在這個配置檔案中寫。

例如,現在定義一個 Book 類:

public class Book {
    private Long id;
    private String name;
    private String author;
    //省略 getter/setter
}

然後,在 application.properties 檔案中定義屬性:

book.name=三國演義
book.author=羅貫中
book.id=1

按照傳統的方式(Spring中的方式),可以直接通過 @Value 註解將這些屬性注入到 Book 物件中:

@Component
public class Book {
    @Value("${book.id}")
    private Long id;
    @Value("${book.name}")
    private String name;
    @Value("${book.author}")
    private String author;
    //省略getter/setter
}

注意

Book 物件本身也要交給 Spring 容器去管理,如果 Book 沒有交給 Spring 容器,那麼 Book 中的屬性也無法從 Spring 容器中獲取到值。

配置完成後,在 Controller 或者單元測試中注入 Book 物件,啟動專案,就可以看到屬性已經注入到物件中了。

一般來說,我們在 application.properties 檔案中主要存放系統配置,這種自定義配置不建議放在該檔案中,可以自定義 properties 檔案來存在自定義配置。

例如在 resources 目錄下,自定義 book.properties 檔案,內容如下:

book.name=三國演義
book.author=羅貫中
book.id=1

此時,專案啟動並不會自動的載入該配置檔案,如果是在 XML 配置中,可以通過如下方式引用該 properties 檔案:

<context:property-placeholder location="classpath:book.properties"/>

如果是在 Java 配置中,可以通過 @PropertySource 來引入配置:

@Component
@PropertySource("classpath:book.properties")
public class Book {
    @Value("${book.id}")
    private Long id;
    @Value("${book.name}")
    private String name;
    @Value("${book.author}")
    private String author;
    //getter/setter
}

這樣,當專案啟動時,就會自動載入 book.properties 檔案。

這只是 Spring 中屬性注入的一個簡單用法,和 Spring Boot 沒有任何關係。

型別安全的屬性注入

Spring Boot 引入了型別安全的屬性注入,如果採用 Spring 中的配置方式,當配置的屬性非常多的時候,工作量就很大了,而且容易出錯。

使用型別安全的屬性注入,可以有效的解決這個問題。

@Component
@PropertySource("classpath:book.properties")
@ConfigurationProperties(prefix = "book")
public class Book {
    private Long id;
    private String name;
    private String author;
    //省略getter/setter
}

這裡,主要是引入 @ConfigurationProperties(prefix = "book") 註解,並且配置了屬性的字首,此時會自動將 Spring 容器中對應的資料注入到物件對應的屬性中,就不用通過 @Value 註解挨個注入了,減少工作量並且避免出錯。

總結

application.properties 是 Spring Boot 中配置的一個重要載體,很多元件的屬性都可以在這裡定製。它的用法和 yaml 比較類似,關於 yaml 配置,大家可以參考 Spring Boot 中的 yaml 配置簡介

本文案例我已上傳到 GitHub:https://github.com/lenve/javaboy-code-samples

好了,有問題歡迎留言討論。

關注公眾號牧碼小子,專注於 Spring Boot+微服務,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!

是時候搞清楚 Spring Boot 的配置檔案 application.properties 了!

相關文章