SpringBoot-03 yaml+JSR303

SpringBoot-03 yaml+JSR303

Yaml

1.配置文件

SpringBoot使用一個全局的配置文件 , 配置文件名稱是固定的

YAML是 “YAML Ain’t a Markup Language” (YAML不是一種標記語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思其實是:”Yet Another Markup Language”(仍是一種標記語言)

這種語言以數據作為中心,而不是以標記語言為重點!

  • application.properties

    • 語法結構 :key=value
  • application.yaml

    • 語法結構 :key: 空格 value

配置文件的作用 :修改SpringBoot自動配置的默認值,因為SpringBoot在底層都給我們自動配置好了;

SpringBoot可以有多個配置文件,但是他會自動識別後綴名識別優先順序。

2.Yaml配置

通過對比XMLpropertiesYaml文件:

比如我們可以在配置文件中修改Tomcat 默認啟動的埠號

XML文件

<server>
    <port>8081<port>
</server>

properties文件

server.port=8081

1

Yaml文件

server:
  port: 8081

2

這時候訪問路徑為://localhost:8081/ ,埠號已經發生變化。

3.yaml基礎語法

語法要求嚴格:

1、空格不能省略

2、以縮進來控制層級關係,只要是左邊對齊的一列數據都是同一個層級的。

3、屬性和值的大小寫都是十分敏感的。

字面量:普通的值 [ 數字,布爾值,字元串 ]

字面量直接寫在後面就可以 , 字元串默認不用加上雙引號或者單引號;

k: v

注意:

  • 「 」 雙引號,不會轉義字元串裡面的特殊字元 , 特殊字元會作為本身想表示的意思;

    比如 :name: “kuang \n shen” 輸出 :kuang 換行 shen

  • ” 單引號,會轉義特殊字元 , 特殊字元最終會變成和普通字元一樣輸出

    比如 :name: 『kuang \n shen』 輸出 :kuang \n shen

對象、Map(鍵值對)

#對象、Map格式
k: 
 v1:
 v2:

在下一行來寫對象的屬性和值得關係,注意縮進;比如:

people:
    name: zc
    age: 20

行內寫法

people: {name: zc,age: 20}     #對象用{}

數組( List、set )

用 – 值表示數組中的一個元素,比如:

pets:
 - cat
 - dog
 - pig

行內寫法

pets: [cat,dog,pig]    #數組用[]

yaml文件更強大的地方在於,他可以給我們的實體類直接注入匹配值!

4.yaml注入配置文件

該項目中的 class類 都要在 啟動類同級目錄 下才可以

4.1 @Vlaue注入

1.項目中的resources資源文件夾下新建一個文件 application.yaml

2.創建實體類

@Component           //將實體類註冊到容器中
public class people {
    private String name;
    private int age;
    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}

3.使用 @Vlaue 註解

  @Component           //將實體類註冊到容器中
public class people {
    @Value("zc")
    private String name;
    
    @Value("20")
    private int age;
    
    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}  

4.進行測試

test中進行,不要在啟動器

@SpringBootTest
class ZcApplicationTests {

    @Autowired
    people people;

    @Test
    void contextLoads() {
        System.out.println(people);
    }

}

3

4.2 Yaml配置文件注入

1.創建一個新的實體類

@Component               //註冊bean到容器中
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private people people;

    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}

2.在yaml配置文件進行注入

person:
  name: zc
  age: 20
  happy: true
  birth: 2000/10/29
  maps: {k1: v1,k2: v2}
  lists:
    - a
    - b
    - c
  people:
    name: zc
    age: 20

3.注入到實體類中

@ConfigurationProperties作用:
將配置文件中配置的每一個屬性的值,映射到這個組件中;
告訴SpringBoot將本類中的所有屬性和配置文件中相關的配置進行綁定
參數 prefix = 「person」 : 將配置文件中的person下面的所有屬性一一對應
*/
@Component               //註冊bean到容器中
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private people people;

    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}

4.這時候會出現一個問題,打開後,提示需要加入依賴

4

5

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
</dependency>

5.測試運行

@SpringBootTest
class ZcApplicationTests {

    @Autowired
    Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

6

注意:將配置文件的key 值 和 屬性的值設置為不一樣,則結果輸出為null,注入失敗

4.3 載入指定的配置文件

@PropertySource :載入指定的配置文件;

@configurationProperties:默認從全局配置文件中獲取值;

1.在resources共享文件夾下新建一個person.properties文件

name=zc1

2.在我們的實體類中指定載入文件

@Component 
@PropertySource(value = "classpath:person.properties")  
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private people people;

    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}

注意:

@PropertySource() ——-@PropertySources()

這兩個只差一個s,有時候看不清就會補充出錯

在這裡使用的是@PropertySource(),只引用了一個資源文件

用法對比:

都可以載入多個配置文件,但是@PropertySources可以添加約束。

@PropertySource(value = {"classpath:person.properties","classpath:test.properties"})


@PropertySources({@PropertySource(value = "classpath:person.properties",ignoreResourceNotFound = true,encoding = "UTF-8"),
        @PropertySource(value = "classpath:test.properties",ignoreResourceNotFound = true,encoding = "UTF-8")})

3.測試運行

@SpringBootTest
class ZcApplicationTests {
    @Autowired
    Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

7

4.4 配置文件佔位符

配置文件還可以編寫佔位符生成隨機數

person:
  name: ${random.uuid}      #隨機uuid
  age: ${random.int}        #隨機int
  happy: true
  birth: 2000/10/29
  maps: {k1: v1,k2: v2}
  lists:
    - a
    - b
    - c
  people:
    name: zc
    age: 20

5.回顧properties配置

上面採用的yaml方法都是最簡單的方式。

開發中最常用的;也是springboot所推薦的那我們來嘮嘮其他的實現方式;

【注意】properties配置文件在寫中文的時候,會有亂碼 , 我們需要去IDEA中設置編碼格式為UTF-8

settings–> Editor–>FileEncodings 中配置:

8

測試案例:

1、新建一個實體類User

@Component
public class User {
    private String name;
    private int age;
    private String sex;
    
    // 有參無參構造方法
    // get、set方法
    // toString()方法  
}

2、編輯配置文件 user.properties

user.name=zc
user.age=20
user.sex=男

3.@Value注入

@Value("${user.name}") //從配置文件中取值
private String name;
@Value("#{9*2}")  // #{SPEL} Spring表達式
private int age;
@Value("男")  // 字面量
private String sex;

4.測試運行

@SpringBootTest
class ZcApplicationTests {
    @Autowired
    User user;

    @Test
    void contextLoads() {
        System.out.println(user);
    }
}

這裡測試的是完全引用user.properties的配置

9

6.Yaml總結

1、@ConfigurationProperties只需要寫一次即可 , @Value則需要每個欄位都添加

2、鬆散綁定:比如我的yml中寫的last-name,這個和lastName是一樣的, - 後面跟著的字母默認是大寫的。這就是鬆散綁定。

3、**JSR303數據校驗 **, 這個就是在欄位是增加一層過濾器驗證 , 可以保證數據的合法性

4、複雜類型封裝,yml中可以封裝對象 , 使用value就不支援

結論:

配置yml和配置properties都可以獲取到值 , 強烈推薦 yml;

如果我們在某個業務中,只需要獲取配置文件中的某個值,可以使用一下 @value;

如果說,我們專門編寫了一個JavaBean來和配置文件進行一一映射,就直接@ConfigurationProperties

JSR303

1.使用方法

Springboot中可以用@validated來校驗數據,如果數據異常則會統一拋出異常,方便異常中心統一處理。

這裡來寫個註解讓我們的name只能支援Email格式;

這裡新版本要注意:

需要加上validation啟動器

<dependency>
     <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

之後加入註解:

@Component               
@ConfigurationProperties(prefix = "person")
@Validated            //數據校驗
public class Person {
    @Email()
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private people people;

    // Set/Get方法
    // 有參/無參方法
    // toString()方法
}

運行會發現錯誤:

1

2.常見參數

@NotNull(message="名字不能為空")
private String userName;
@Max(value=120,message="年齡最大不能查過120")
private int age;
@Email(message="郵箱格式錯誤")
private String email;

空檢查
@Null       驗證對象是否為null
@NotNull    驗證對象是否不為null, 無法查檢長度為0的字元串
@NotBlank   檢查約束字元串是不是Null還有被Trim的長度是否大於0,只對字元串,且會去掉前後空格.
@NotEmpty   檢查約束元素是否為NULL或者是EMPTY.
    
Booelan檢查
@AssertTrue     驗證 Boolean 對象是否為 true  
@AssertFalse    驗證 Boolean 對象是否為 false  
    
長度檢查
@Size(min=, max=) 驗證對象(Array,Collection,Map,String)長度是否在給定的範圍之內  
@Length(min=, max=) string is between min and max included.

日期檢查
@Past       驗證 Date 和 Calendar 對象是否在當前時間之前  
@Future     驗證 Date 和 Calendar 對象是否在當前時間之後  
@Pattern    驗證 String 對象是否符合正則表達式的規則

3.多配置切換

配置文件可以存放的位置:

1.file:./config/
2.file:./
3.classpath:/config/
4.classpath:/

優先順序也是按這個1234排序,下圖為項目中位置

2

3.1 多環境配置

profile是Spring對不同環境提供不同配置功能的支援,可以通過激活不同的環境版本,實現快速切換環境

我們在主配置文件編寫的時候,文件名可以是 application-{profile}.properties/yml , 用來指定多個環境版本;

例如:

application-test.properties 代表測試環境配置

application-dev.properties 代表開發環境配置

但是Springboot並不會直接啟動這些配置文件,它默認使用application.properties主配置文件

我們需要通過一個配置來選擇需要激活的環境:

application.properties選擇你想用的環境配置;

#我們啟動SpringBoot,就可以看到已經切換到dev/test下的配置了
spring.profiles.active=test
#或者
spring.profiles.active=dev

3.2 yaml的多文檔塊

server:
  port: 8081
#選擇要激活那個環境塊
spring:
  profiles:
    active: dev

---
server:
  port: 8082
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: test

注意:如果yml和properties同時都配置了埠,並且沒有激活其他環境 , 默認會使用properties配置文件的

個人部落格為:
MoYu’s HomePage
MoYu’s Gitee Blog