全局配置文件
全局配置文件能夠對一些默認配置值進行修改。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文件格式的行內式寫法的配置文件的屬性注入都不支持,如果對其賦值會報錯。