SpringBoot基礎學習(二) SpringBoot全域性配置檔案及配置檔案屬性值注入

blayn發表於2021-06-02

全域性配置檔案

全域性配置檔案能夠對一些預設配置值進行修改。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檔案格式的行內式寫法的配置檔案的屬性注入都不支援,如果對其賦值會報錯。

相關文章