基本知識點:
什么是yml/yaml?:
YAML是 "YAML Ain't a Markup Language" (YAML不是一種標記語言)的 遞歸縮寫
在開發的這種語言時,YAML 的意思其實是:
"Yet Another Markup Language"(仍是一種標記語言)
這種語言以數據作為中心,而不是以標記語言為重點!
為什么要使用yml/yaml來進行開發?
優點:
- 語法要簡單,靈活
- 能夠寫注釋
- 能夠比較方便的覆蓋參數值(方便書寫或者debug)
- 能夠重用配置片段,
比較大一點的project中,
經常有很多地方的配置需要保持一致,
最好的辦法就是引入變量和引用的概念- 可以繼承
基本語法:
八大基本類型 + 字符串:
格式:
目標成員名: 普通的值
注意:
- 字符串默認不用加上雙引號或者單引號
- '' (單引號):
不會 轉義 字符串里面的特殊字符 ,
特殊字符最終會變成和普通字符一樣輸出比如:msg: 'hello \n spring boot'
輸出:hello \n spring boot
- "" (雙引號):
會轉義特殊字符 ,
特殊字符會作為本身想表示的意思比如:
msg: "hello \n spring boot"
則會 輸出 :hello 換行 spring boot
對象:
格式:
目標對象名:
對象的成員1: 1成員的值
對象的成員2: 2成員的值
...
Map(雙列集合):
格式:
目標map的名稱:
key1: value1
key2: value2
...
數組(List、Set 等單列集合):
格式:
目標單列集合名:
- 集合中的值1
- 集合中的值2
- 集合中的值3
- ...
或
目標單列集合名: [集合中的值1, 集合中的值2, 集合中的值3, ...]
注意點:
- :(冒號)后的空格不能省略
- 以縮進來控制層級關系,
只要是左邊對齊的一列數據都是同一個層級的- 屬性和值的大小寫都是十分敏感的
屬性的注入:
在本人之前的博文中曾講到過:
配置文件 的 目的 是:
將配置文件中的值注入給代碼中 需要的地方
在SpringBoot中,提供了相關的注解,來注入相應的值:
@ConfigurationProperties注解:
作用:
一般都是配合該注解的 prefix屬性,
來指定要進行注入的 配置的值
注意:
- prefix屬性的值,為配置文件中的 要賦值的段落名
- 實體類中要被賦值的成員名,要與 配置文件中的對應段落名 一致
例如:
pet:
name: "吉吉國王"
yell: "嗚~"
package edu.youzg.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author: Youzg
* @CreateTime: 2020-06-17 15:17
* @Description: 帶你深究Java的本質!
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "pet")
@Component
public class Pet {
private String name;
private String yell;
}
隨機數 的生成:
格式:
${random.隨機數的類型}
而上述的 隨機數類型,總共分為 4種:
分類:
- int(可設置上限值)
- long(可設置上限值)
- uuid(隨機字符串,更不容易 重復)
- value(隨機字符串)
例如:
id: ${random.uuid} # value int long
@ConfigurationProperties注解 作為 springBoot 所提供的屬性注入注解,
也提供了一些非常強大的功能,其中最常用的就是 松散綁定:
松散綁定:
定義:
yml/yaml配置文件 中 配置 的 鍵名為 xx_xx形式
實體類 的 成員名 為 駝峰式
也可進行注入
例如:
myFan:
the_pets:
- name: "加菲"
yell: "喵~"
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "myFan")
public class Fan {
private List<Pet> thePets;
}
講到 屬性的注入問題,有的同學可能就會想到:
當初學習spring Framework的時候,所使用的 @Value注解
那么,現在本人就來講解下 @ConfigurationProperties注解 和 @Value注解 之間的 區別 以及 各自的應用場景:
@ConfigurationProperties注解 與 @Value注解:
首先本人來列舉下這兩個注解的區別:
區別:
比較項目 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入 配置文件中的屬性 | 一個個指定注入 配置文件中的屬性 |
松散綁定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303校驗 | 支持 | 不支持 |
復雜封裝類型 | 支持 | 不支持 |
那么,區別這么多,這兩個注解的應用場景是什么呢?
應用場景:
- @Value注解:
只是在某個業務邏輯中需要獲取一下配置文件中的某項值- @ConfigurationProperties注解:
專門編寫了一個JavaBean來和配置文件進行映射
在有些情況下,我們不希望application配置文件中的屬性配置太過繁瑣
需要將有些屬性的配置放到其它的配置文件中去
那么,針對這種需求,springBoot提供了 @PropertySource注解:
注入 其它配置文件的屬性 —— @PropertySource注解:
例如:
首先,本人來提供一個 pet.properties配置文件:
pet.name=killer queen
pet.yell=wryyyyyyyyy
接下來,我們來修改下 Pet類 的 內容:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@PropertySource({"classpath:pet.properties"}) // 指定要被 “額外加載” 的配置文件的 全路徑名
@ConfigurationProperties(prefix = "pet") // 指定前綴
@Component
public class Pet {
private String name;
private String yell;
}
那么,我們來做個小測試:
import edu.youzg.entity.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ProfileDemoApplicationTests {
@Autowired
private Pet myPet;
@Test
public void myTest() {
System.out.println(myPet);
}
}
運行結果:
多配置文件 問題:
在有的大型項目中,我們或許能夠看到 這樣的情況:
一個項目,配置了多個配置文件(即:配置了多個application.yml)
配置文件 優先級:
springBoot提供了 四個 可以 放置配置文件 的 位置:
- file: ./config(項目路徑下的config文件夾配置文件)
- file: ./(項目路徑下配置文件)
- classpath: /config(資源路徑下的config文件夾配置文件)
- classpath: /(資源路徑下配置文件)
如下圖所示:
指定 開發環境:
在我們今后的工作中,可能會遇到這樣的情況:
在測試開發時,操作的是一些數據庫
在產品發布時,使用的是另一些數據庫
那么,這樣的話,我們就需要配置多套配置文件,操作起來比較麻煩
因此,spring Boot 提供了切換開發環境的功能:
核心操作:
在application-default.yml文件中,增加如下代碼:
spring:
profiles:
active: 指定的配置文件的“后綴名”
例如:
首先,我們需要一個默認的配置文件:
其 文件名 必須為:application-default.yml(或 application-default.properties):
server:
port: 8085
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/dbstudy?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
devtools:
restart:
log-condition-evaluation-delta: true
exclude: static/css/**, static/js/**
thymeleaf:
cache: false
prefix: classpath:/templates/views/
suffix: .html
# 指定開發環境(指定配置文件中 沒配置則填充,配置了則覆蓋)
profiles:
active: dev
#mapper-locations 映射所在的路徑
#給模型的包起個別名
mybatis:
mapper-locations: classpath:/mapper/*Mapper.xml
type-aliases-package: edu.youzg.about_boot.model
#打印日志 SQL 執行
logging:
level:
edu:
youzg:
about_boot:
mapper: debug
(本例 主要是 配置port,以及 指定了環境的配置)
之后,本人再來給出 開發環境 和 產品環境 的配置文件:
application-dev.yml:
server:
port: 8100
application-prod.yml:
server:
port: 8090
那么,當我們再次運行時,控制台就會顯示如下結果:
可以看到:端口號變為了我們指定的端口
多配置文件 的合並:
若是我們想要在激活一個配置文件同時激活多個配置,
就需要在目標開發環境中,加入
spring:
profiles:
include:
- 指定的配置文件的“后綴名1”
- 指定的配置文件的“后綴名2”,
- ...
(注意:若重名,include中的值會覆蓋 原配置文件的值)
但是,如上的多開發環境也可以在一個配置文件中實現:
單配置文件 配置 多開發環境:
核心步驟:
將每個 子開發環境 放在主開發環境下,
並使用
---
分隔開,
再通過
spring:
profiles:
active: 指定的配置文件的“后綴名”
來指定
例子:
server:
port: 8080
spring:
profiles:
active: test
---
spring:
profiles: test
server:
port: 9000
---
spring:
profiles: production
server:
port: 9050
那么,當我們運行之后,控制台就會顯示如下結果:
使用展示:
本人先來給出一個寵物類:
package edu.youzg.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author: Youzg
* @CreateTime: 2020-06-17 15:17
* @Description: 帶你深究Java的本質!
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "pet")
@Component
public class Pet {
private String name;
private String yell;
}
接下來,本人給出一個 粉絲類:
package edu.youzg.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
/**
* @Author: Youzg
* @CreateTime: 2020-06-17 15:13
* @Description: 帶你深究Java的本質!
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "myFan")
public class Fan {
private String name;
private String id;
private Date birthday;
private Integer age;
private List<Pet> thePets;
}
對應的 yml配置文件:
myFan:
name: "右轉哥的小迷妹"
id: ${random.uuid} # value int long
birthday: 2020/6/18
the_pets:
- name: "加菲"
yell: "喵~"
- name: "史努比"
yell: "汪~"
最后是 測試類:
package edu.youzg.demo;
import edu.youzg.demo.model.Fan;
import edu.youzg.demo.model.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private Fan fan;
@Test
void contextLoads() {
System.out.println(fan);
}
}
現在,本人來展示下運行結果:
可以看到:
本人沒有配置age成員的值,
因此,除了age成員為null,其余成員的值都為配置文件中所配置的值