SpringBoot 配置的載入
SpringBoot配置及環境變數的載入提供許多便利的方式,接下來一起來學習一下吧!
本章內容的原始碼按實戰過程採用小步提交,可以按提交的節點一步一步來學習,倉庫地址:https://github.com/zhouweixin/spring-boot-configuration。
環境:
- java: 1.8.0_265
- gradle: 6.6.1
1 準備
用你喜歡的方式建立一個SpringBoot工程,並寫一個hello的介面,及相應的整合測試,進行實驗吧!
1.1 hello介面程式碼
HelloController.java
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello world!";
}
}
1.2 hello整合測試程式碼
HelloControllerTest.java
@SpringBootTest
@AutoConfigureMockMvc
class HelloControllerTest {
@Autowired
MockMvc mockMvc;
@Test
void hello() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:8080/hello"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.is("Hello world!")));
}
}
2 註解@Value
2.1 介紹
@Value通過直接註解在屬性上為屬性設定
如下所示,為name設定值為tangseng
HelloController.java
@Value("tangseng")
private String name;
2.2 載入配置檔案
當然,上面的寫法不涉及配置檔案的讀取,但是從配置檔案載入資料也是同樣簡單
如下所示,在${}中用json的方式設定配置檔案中設定的key值
HelloController.java
@Value("${value.string}")
private String valueString;
配置檔案的內容為
application.properties
value.string=sunwukong
2.3 資料型別轉換
當然,@Value的功能還遠不止於此,它可以實現資料型別的轉換
即,在配置檔案中配置的所有內容是沒有資料型別的,@Value會根據屬性的型別,實現自動轉換
如下所示,基本資料型別@Value註解都是可以正確轉換的,使用起來有沒有感覺很簡單呢?
application.properties
value.int=1
value.float=1.11
value.string=sunwukong
value.bool=true
HelloController.java
@Value("${value.int}")
private int valueInt;
@Value("${value.float}")
private float valueFloat;
@Value("${value.string}")
private String valueString;
@Value("${value.bool}")
private boolean valueBool;
2.4 預設值
寫到這裡,你肯定認為@Value註解的功能就結束了
然而,並沒有,@Value還可以設定預設值
即,假如配置檔案中沒有配置該屬性,也可以有預設值兜底的
預設值的設定格式如下所示
HelloController.java
@Value("${value.double:2.22}")
private double valueDouble;
2.5 時間轉換
這次,你一定又一次認為@Value的學習結束了,但是想再分享@Value對時間的處理,因為實際專案中經常會配置超時時間等類似的時間,比較實用
假如配置檔案裡配置了timeout=60
,你認為是60s呢還是60ms,或是60m,是不是有點不清楚呢?
因此,多是配置成timeout=60s
, 利用@DurationUnit進行單位的轉換
還是看個例子比較直觀些
首先配置一個10分鐘
application.properties
value.time=10m
然後用秒
去解析,看看結果是否正確,這裡悄悄告訴你,結果依然是正確的,轉成了600s
HelloController.java
@Value("${value.time}")
@DurationUnit(ChronoUnit.SECONDS)
private Duration time;
2.6 整合測試
接下來,寫個介面及整合測試,測試一下結果
HelloController.java
@GetMapping("/helloValue")
public Object helloValue() {
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("valueInt", valueInt);
map.put("valueFloat", valueFloat);
map.put("valueString", valueString);
map.put("valueBool", valueBool);
map.put("valueDouble", valueDouble);
return map;
}
HelloControllerTest.java
@Test
void helloValue() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:8080/helloValue"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.is("tangseng")))
.andExpect(MockMvcResultMatchers.jsonPath("$.valueInt", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$.valueFloat", Matchers.is(1.11)))
.andExpect(MockMvcResultMatchers.jsonPath("$.valueString", Matchers.is("sunwukong")))
.andExpect(MockMvcResultMatchers.jsonPath("$.valueBool", Matchers.is(true)))
.andExpect(MockMvcResultMatchers.jsonPath("$.valueDouble", Matchers.is(2.22)))
.andExpect(MockMvcResultMatchers.jsonPath("$.time", Matchers.is("600s")));
}
當然也可以用請求檢視一下結果
$ curl http://localhost:8080/helloValue
{"valueString":"sunwukong","name":"tangseng","valueDouble":2.22,"time":"600s","valueInt":1,"valueFloat":1.11,"valueBool":true}
3 註解@ConfigurationProperties
3.1 介紹
@ConfigurationProperties實現了更加豐富的功能,但是該屬性需要配置@ConfigurationPropertiesScan使用
即,首先需要將@ConfigurationPropertiesScan註解到啟動類上,即XxxApplication.java
然後便可以利用@ConfigurationProperties上
@ConfigurationProperties是用來註解類上,用來批量從配置檔案中載入資料
比如,配置中有如下屬性
application.properties
student.name=xiaoming
student.email=123456@qq.com
student.age=18
便可以定義Student類,並將@ConfigurationProperties註解其上
注意:屬性名需要和配置檔案裡對應的名字相同,你肯定觀察到了
Student.java
@ConfigurationProperties("student")
public class Student {
private String name;
private String email;
private int age;
// ... 省略setter, getter方法, setter方法必須有
}
3.2 載入集合資料
@ConfigurationProperties除了可以讀單值資料,也可以讀List和Map資料
比如,配置檔案裡有如下配置
application.properties
# class.list
student.friends[0]=zhubajie
student.friends[1]=shaheshang
# class.map
student.parent.father=tangseng
student.parent.mother=nverguoguowang
只需要在Student類中再新增兩個屬性即可,不要忘記setter和getter方法喲
Student.java
private List<String> friends;
private Map<String, String> parent;
新增getStudent介面
HelloController.java
@GetMapping("/getStudent")
public Student getStudent() {
return student;
}
3.3 整合測試
HelloControllerTest.java
@Test
void getStudent() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:8080/getStudent"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.is("xiaoming")))
.andExpect(MockMvcResultMatchers.jsonPath("$.email", Matchers.is("123456@qq.com")))
.andExpect(MockMvcResultMatchers.jsonPath("$.age", Matchers.is(18)))
.andExpect(MockMvcResultMatchers.jsonPath("$.friends[0]", Matchers.is("zhubajie")))
.andExpect(MockMvcResultMatchers.jsonPath("$.friends[1]", Matchers.is("shaheshang")))
.andExpect(MockMvcResultMatchers.jsonPath("$.parent.father", Matchers.is("tangseng")))
.andExpect(MockMvcResultMatchers.jsonPath("$.parent.mother", Matchers.is("nverguoguowang")));
}
直接求觀測也是可以的
$ curl http://localhost:8080/getStudent
{"name":"xiaoming","email":"123456@qq.com","age":18,"friends":["zhubajie","shaheshang"],"parent":{"father":"tangseng","mother":"nverguoguowang"}}