全域性配置檔案
全域性配置檔案能夠對一些預設配置值進行修改。SpringBoot 使用一個名為 application.properties 或者 application.yaml的檔案作為全域性配置檔案,該檔案會放在 src/main/resource 目錄或者類路徑的 /config 目錄下,一般會選擇 /resource。下面將講解這兩種配置檔案:
(1)application.properties配置檔案
使用Spring Initializr方式構建的SpringBoot專案會自動在 src/main/resource 目錄下生成一個 application.properties 配置檔案,SpringBoot專案啟動時會自動載入 application.properties 配置檔案。
我們可以在 application.properties 配置檔案中定義SpringBoot專案的相關屬性,包括系統屬性、環境變數及命令引數等資訊,也可以是自定義配置檔名稱和位置,如下所示:
server.port=8081 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.config.additional-location= spring.config.location= spring.config.name=application
接下來,通過一個簡單案例對SpringBoot專案中 application.properties 配置檔案的使用進行講解。
操作步驟:
1、先在專案的 com.hardy.springboot_demo 包下建立一個pojo包,並在該包下建立兩個實體類 Pet和Person:
package com.hardy.springboot_demo.pojo; /** * @Author: HardyYao * @Date: 2021/5/30 */ public class Pet { private String type; private String name; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Pet{" + "type='" + type + '\'' + ", name='" + name + '\'' + '}'; } }
package com.hardy.springboot_demo.pojo; /** * @Author: HardyYao * @Date: 2021/5/30 */ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; import java.util.Map; @Component // 用於將Person類作為Bean注入到Spring容器中 @ConfigurationProperties(prefix = "person") // 將配置檔案中以person開頭的屬性注入到該類中 public class Person { private int id; // id private String name; // 姓名 private List hobby; // 愛好 private String[] family; // 家庭成員 private Map map; private Pet pet; // 寵物 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getHobby() { return hobby; } public void setHobby(List hobby) { this.hobby = hobby; } public String[] getFamily() { return family; } public void setFamily(String[] family) { this.family = family; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } public Pet getPet() { return pet; } public void setPet(Pet pet) { this.pet = pet; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", hobby=" + hobby + ", family=" + Arrays.toString(family) + ", map=" + map + ", pet=" + pet + '}'; } }
@ConfigurationProperties(prefix = "person") 註解的作用是將配置檔案中以person開頭的屬性值通過setXX()方法注入到實體類對應屬性中。
@Component註解的作用是將當前注入屬性值的Person類物件作為Bean元件放到Spring容器中,只有這樣才能被@ConfigurationProperties註解進行賦值。
2、編寫專案的 application.properties 配置檔案,在該配置檔案中編寫需要對Person類設定的配置屬性:
person.id=1 person.name=hardy person.hobby=吃肉,看書,學習,寫程式碼 person.family=爸爸,媽媽 person.map.k1=v1 person.map.k2=v2 person.pet.type=cat person.pet.name=Hello Kitty
編寫 application.properties 配置檔案時,由於要配置為Person物件屬性值是我們自己定義的,SpringBoot無法自動識別,所以不會有書寫提示。在實際開發中,為了出現程式碼提示來提高配置效率,我們可以使用@ConfigurationProperties註解進行配置檔案屬性值注入,這需要在pom.xml檔案中新增一個SpringBoot提供的配置器依賴:
<!-- 引入配置器依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
新增上述依賴後,需要重新執行專案啟動類或者使用“Ctrl+F9”快捷鍵(即Build Project)重構當前SpringBoot專案即可。
3、在專案測試類中引入Person實體類Bean,進行測試:
package com.hardy.springboot_demo; import com.hardy.springboot_demo.pojo.Person; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest // 標記為SpringBoot單元測試類,並載入專案的ApplicationContext上下文環境 class SpringbootDemoApplicationTests { @Autowired private Person person; @Test void configurationTest() { System.out.println(person); } }
注意:這裡需要對IDEA進行一下編碼設定,設定為UTF-8,不然,在控制檯列印的中文內容會出現亂碼的現象,具體配置如下所示:
列印測試結果:
可以看到,測試方法configurationTest()執行成功,也列印出了Person實體類物件。說明我們的 application.properties 配置檔案配置正確,並通過相關注解自動完成了屬性注入。
(2)application.yaml配置檔案
YAML檔案格式是SpringBoot支援的一種用於編寫配置檔案的序列化語言,它與JSON有些相似,被稱為JSON的超集。YAML的設計是為了友好可讀性,主要用於配置資訊的編寫,而JSON的設計目的則是為了簡單和通用,主要用於儲存資料和應用層資料通訊使用。
application.yaml 配置檔案的工作原理和 application.properties 配置檔案是相同的,只不過 application.yaml 配置檔案看起來更簡潔一些。
- YAML檔案的擴充名可以用.yml或這.yaml。
- application.yml檔案使用“key: value”(注意,中間要有一個空格)格式配置屬性,使用縮排控制層級關係。
這裡,針對不同資料型別的屬性值,介紹一下YAML。
1、value值為普通資料型別(例如數字、字串、布林等)
當YAML配置檔案中配置的屬性值為普通資料型別時,可以直接配置對應的屬性值,同時對於字串型別的屬性值,不需要額外新增引號,示例程式碼如下:
server: port: 8080 path: /demo
上述程式碼用於配置server的port和path屬性,port和path屬於同一個級別。
2、value值為陣列和單列集合
當YAML配置檔案中配置的屬性值為資料或單列集合型別時,主要有兩種編寫方式:縮排式寫法和行內式寫法。
其中,縮排式寫法還有兩種表現形式,示例程式碼如下:
person: hobby: - eat - read - study - coding
或者使用如下方式:
person: hobby: eat, read, study, coding
上述程式碼中,在YAML配置檔案中通過兩種縮排式寫法對person物件的單列集合(或陣列)型別的hobby賦值為eat,read,study和coding。其中一種形式為“- 屬性值”(注意,中間要有一個空格),另一種形式為多個屬性值之間用逗號隔開(注意,最後一個屬性值後面不能加逗號)。
行內式寫法如下:
person: hobby: [eat,read,study,coding]
通過上述程式碼對比發現,YAML配置檔案的行內式寫法更加簡潔和方便。此外,包含屬性值的中括號“[]”還可以進一步省略,在進行屬性賦值時,程式會自動匹配和校對。
3、value值為Map集合與物件
當YAML配置檔案中配置的屬性值為Map集合或物件型別時,YAML配置檔案同樣可以分為兩種書寫方式:縮排式寫法和行內式寫法。
其中,縮排式寫法的示例程式碼如下:
person: map: k1: v1 k2: v2
對應的行內式寫法如下:
person: map: {k1: v1,k2: v2}
在YAML配置檔案中,配置的屬性值為Map集合或物件型別時,縮排式寫法的形式按照YAML檔案格式常規寫法編寫即可,而行內式寫法的屬性值要用大括號“{}”包含。
接下來,在Properties配置檔案演示案例的基礎上,通過配置 application.yaml配置檔案 對Person物件進行賦值,具體使用如下:
(1)在專案的resources目錄下,新建一個 application.yaml配置檔案,在該配置檔案中編寫Person類的配置屬性:
# 對實體類物件Person進行屬性配置
person: id: 1 name: hardy hobby: [吃肉,讀書,學習,寫程式碼] family: [爸爸,媽媽] map: {k1: v1,k2: v2} pet: {type: cat,name: Hello Kitty}
注意:本次使用 application.yaml配置檔案 進行測試時需要先將 application.properties配置檔案 中編寫的配置給註釋掉,不然的話 application.properties配置檔案 會覆蓋掉 application.yaml配置檔案 中的配置。
(2)再次進行測試
可以看到,測試方法configurationTest()同樣執行成功,並正確列印出了Person實體類物件。
配置檔案屬性值的注入
使用SpringBoot全域性配置檔案設定屬性時:
- 如果配置屬性是SpringBoot已有屬性,例如服務埠server.port,那麼SpringBoot內部會自動掃描、讀取這些配置檔案中的屬性值並覆蓋預設屬性。
- 如果配置的屬性是使用者自定義屬性,例如剛剛自定義的Person實體類屬性,還必須在程式中注入這些配置屬性方可生效。
SpringBoot支援多種注入配置檔案屬性的方式,下面來介紹如何使用註解@ConfigurationProperties和@Value注入屬性。
(1)使用@ConfigurationProperties注入屬性
SpringBoot提供@ConfigurationProperties註解用於快速、方便地將配置檔案中的自定義屬性值批量注入到某個Bean物件的多個對應屬性中。假設現在有一個配置檔案,如果使用@ConfigurationProperties諸如配置檔案的屬性,示例程式碼如下:
@Component // 用於將Person類作為Bean注入到Spring容器中 @ConfigurationProperties(prefix = "person") // 將配置檔案中以person開頭的屬性注入到該類中 public class Person { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } }
上述程式碼使用@Component和@ConfigurationProperties(prefix = “person”)將配置檔案中的每個屬性都對映到person類元件中。
(2)使用@Value注入屬性
@Value註解是Spring框架提供的,用來讀取配置檔案中的屬性值並逐個注入到Bean物件的對應屬性中,SpringBoot框架從Spring框架中對@Value進行了預設繼承,所以在SpringBoot框架中還可以使用該註解讀取和注入配置檔案屬性值。使用@Value注入屬性的示例程式碼如下:
@Component public class Person { @Value("${person.id}") private int id; }
在上述程式碼中,使用@Component和@Value注入Person實體類的id屬性。其中@Value不僅可以將配置檔案的屬性注入Person的id屬性,還可以直接給id屬性進行賦值,這點是@ConfigurationProperties不支援的。
演示@Value註解讀取並注入配置檔案屬性的使用:
(1)在專案的 com.hardy.springboot_demo.pojo 包下建立一個實體類 Student,並使用@Value註解注入屬性:
package com.hardy.springboot_demo.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @Author: HardyYao * @Date: 2021/5/30 */ @Component public class Student { @Value("${person.id}") private int id; @Value("${person.name}") private String name; // 名稱 // 不需要set方法 @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
Student類使用@Value註解將配置檔案的屬性值讀取和注入。
從上述程式碼可以看出,使用@Value註解方式需要對每一個屬性進行注入設定,同時又免去了屬性的setXXX()方法。
(2)再次編寫測試方法進行測試
package com.hardy.springboot_demo; import com.hardy.springboot_demo.pojo.Student; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest // 標記為SpringBoot單元測試類,並載入專案的ApplicationContext上下文環境 class SpringbootDemoApplicationTests { @Autowired private Student student; @Test void studentTest() { System.out.println(student); } }
列印結果:
可以看到,測試方法studentTest()執行成功,同時正確列印出了Student實體類物件。
注意:本示例中只是使用@Value註解對示例中Student物件的普通型別屬性進行了賦值展示,而@Value註解對於包含Map集合、物件以及YAML檔案格式的行內式寫法的配置檔案的屬性注入都不支援,如果對其賦值會報錯。