1. 程式人生 > >spring boot 2.1學習筆記【四】屬性配置

spring boot 2.1學習筆記【四】屬性配置

spring boot 2.1系列文章目錄

文章目錄

** 從這一章節開始,才進入真正的springboot2.1學習**

屬性配置是springboot中比較常用且重要的功能,很多自定義的配置及自動裝配都依賴該功能

常規屬性配置

@value

假設我們這裡使用@value來注入name:

@RestController
@Slf4j
public class HelloController {
    @Value("${name}")
    private String name;

    @GetMapping("/properties1")
    public String properties1() {
        log.info("name={}", name);
        return
"Welcome to springboot2 world ~"; } }

啟動引數

可以在專案啟動時設定啟動引數,@value可以將值注入到name:
在這裡插入圖片描述

上圖中,我們設定引數:--name="zhangsan",啟動專案,呼叫http://127.0.0.1:8080/properties1介面,可以看到日誌中輸出2018-12-30 15:04:31.699 INFO 12456 --- [nio-8080-exec-1] com.example.controller.HelloController : name=zhangsan
springboot的專案我們一般會將其打成一個jar包執行,那麼也可以通過在執行jar包時傳入:
java -jar springboot2demo-1.0-SNAPSHOT.jar --name="lisi"


在這裡插入圖片描述

application.properties

首先將啟動引數中的–name刪除,以避免影響到我們接下來的測試。

stu.name=zhangsan
stu.age=10

上面定義了兩個變數,我們修改HelloController.java如下:

 @Value("${stu.name}")
    private String name;
    @Value("${stu.age}")
    private String age;

    @GetMapping("/properties1")
    public String properties1() {
        log.info("name={}, age={}", name, age);
        return "Welcome to springboot2 world ~";
    }

執行結果:name=zhangsan, age=10

型別安全的屬性配置(強烈推薦)

上述只是簡單的舉例,但是實際專案中如果全都這樣寫,會比較麻煩,而且容易型別出錯,故官方建議使用型別安全的屬性配置,藉助實體類進行注入,方便使用且型別更加安全。

新建Stu類:

import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "stu") //指定字首為stu
@Data
@ToString
public class Stu {
    private String name;
    private int age;
}

在controller中這樣使用:

@Autowired
private Stu stu;

@GetMapping("/properties1")
public String properties1() {
    log.info("stu={}", stu);
    return "Welcome to springboot2 world ~";
}

執行結果:stu=Stu(name=zhangsan, age=10)}

這樣就可以防止資料配置錯誤,而且使用簡單。如果將age設定為字串則啟動會報錯:
在這裡插入圖片描述

YMAL

目前比較流行ymal, 固接下來都會使用ymal來進行配置。使用ymal需要將application.properties檔名稱改為application.yml(yaml也可以)。

stu:
  name=lisi
  age=20

重啟 服務,輸出結果是一樣的。

接下來的配置我們將使用YMAL及型別安全的方式進行演示。

多種多樣的屬性配置

簡單起見,這裡我就直接一次性編寫到一個實體類了,大家可以根據下面例項程式碼自行嘗試

下面展示簡單資料型別和複雜資料型別:
編寫person.java:

import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "person")
@Data
@ToString
public class Person {
    //各種普通資料型別
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    //複雜型別展示
    private Map<String,Object> map;
    private List<Object> list;
    private List<Dog> dogs;
    private Stu stu;
}

stu.java:

@Component
@ConfigurationProperties(prefix = "stu")
@Data
@ToString
public class Stu {
    private String name;
    private int age;
}

dog/java

@Component
@Data
@ToString
public class Dog {
    private String name;
    private double weight;
}

application.yml;

person:
  lastName: zhangsan
  age: 18
  boss: false
  birth: 2018/05/04 01:02:21
  map: {k1: v1,k2: v2}
  list:
  - lisi
  - good
  dogs:
  - dog:
    name: aaa
    weight: 15
  - dog:
    name: ccc
    weight: 16
  #上面是KV寫法,下面是行內寫法
  stu: {name: lisi, age: 21}

stu:
  name: zhangsan
  age: 18

HelloController:

 @Autowired
    private Stu stu;
    @Autowired
    private Person person;


    @GetMapping("/properties1")
    public String properties1() {
        log.info("stu={}", stu);
        log.info("person={}", person);
        return "Welcome to springboot2 world ~";
    }

執行結果:

stu=Stu(name=zhangsan, age=18)

person=Person(
lastName=zhangsan, 
age=18, 
boss=false, birth=Fri May 04 01:02:21 CST 2018, 
map={k1=v1, k2=v2}, 
list=[lisi, good], 
dogs=[Dog(name=aaa, weight=15.0), Dog(name=ccc, weight=16.0)], 
stu=Stu(name=lisi, age=21))

更多內容參見官網:官方屬性配置教程

配置校驗 valid

使用型別安全的屬性注入方式支援資料檢驗
我們為Person的部分屬性新增校驗:

@Component
@ConfigurationProperties(prefix = "person")
@Data
@ToString
@Validated  //對資料進行校驗
public class Person {
    //各種普通資料型別
    @NotEmpty
    private String lastName;
    @Range(min = 0, max = 10)
    private Integer age;
    //省略程式碼

再次啟動服務,發現啟動失敗,因為age配置了18 ,大於10.

@ConfigurationProperties vs. @Value

在這裡插入圖片描述

profile:針對不同環境使用不同配置

springboot預設使用application.yml中的配置。我們可以在application.yml中使用spring.profiles.active=prod來指定環境配置。也可以在執行過程中通過命令傳遞--spring.profiles.active=prod。當指定了檔案後,如果有相同的配置,那麼指定的檔案中的配置是有效的。

在這裡插入圖片描述

application-prod.yml:

stu:
  name: 鎮關西
  age: 30

application-dev.yml:

stu:
  name: 武松
  age: 29

application.yml新增:

# 這個stu之前就有的,而且三個檔案中都有
stu:
  name: zhangsan
  age: 18

# 指定使用哪個檔案
spring:
  profiles:
    active: dev

執行程式輸出:

stu=Stu(name=武松, age=29)
person=Person(lastName=zhangsan, age=18, boss=false, birth=Fri May 04 01:02:21 CST 2018, map={k1=v1, k2=v2}, list=[lisi, good], dogs=[Dog(name=aaa, weight=15.0), Dog(name=ccc, weight=16.0)], stu=Stu(name=lisi, age=21))

讀者可以嘗試修改上述dev為prod觀察結果。