Spring Boot 2 實戰:經常使用讀取配置的方式

1. 前言

Spring Boot項目中咱們常常須要讀取application.yml配置文件的自定義配置,今天就來羅列一下從yaml讀取配置文件的一些經常使用手段和方法。java

2. 使用@Value註解

首先,會想到使用@Value註解,該註解只能去解析yaml文件中的簡單類型,並綁定到對象屬性中去。spring

felord:
 phone: 182******32
 def:
 name: 碼農小胖哥
 blog: felord.cn
 we-chat: MSW_623
 dev:
 name: 碼農小胖哥
 blog: felord.cn
 we-chat: MSW_623
 type: JUEJIN  
複製代碼

對於上面的yaml配置,若是咱們使用@Value註解的話,冒號後面直接有值的key才能正確注入對應的值。例如felord.phone咱們能夠經過@Value獲取,可是felord.def不行,由於felord.def後面沒有直接的值,它還有下一級選項。另外@Value不支持yaml鬆散綁定語法,也就是說felord.def.weChat獲取不到felord.def.we-chat的值。app

@Value是經過使用SpringSpEL表達式來獲取對應的值的:spa

// 獲取 yaml 中 felord.phone的值 並提供默認值 UNKNOWN
@Value("${felord.phone:UNKNOWN}")
 private String phone;
複製代碼

@Value的使用場景是隻須要獲取配置文件中的某項值的狀況下,若是咱們須要將一個系列的值進行綁定注入就建議使用複雜對象的形式進行注入了。3d

3. 使用@ConfigurationProperties註解

@ConfigurationProperties註解提供了咱們將多個配置選項注入複雜對象的能力。它要求咱們指定配置的共同前綴。好比咱們要綁定felord.def下的全部配置項:code

package cn.felord.yaml.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import static cn.felord.yaml.properties.FelordDefProperties.PREFIX;

/** * @author felord.cn */
@Data
@ConfigurationProperties(PREFIX)
public class FelordDefProperties {
    static final String PREFIX = "felord.def";
    private String name;
    private String blog;
    private String weChat;
}
複製代碼

咱們注意到咱們可使用weChat接收we-chat的值,由於這種形式支持從駝峯camel-case到短橫分隔命名kebab-case的自動轉換。cdn

若是咱們使用@ConfigurationProperties的話建議配置類命名後綴爲Properties,好比Redis的後綴就是RedisProperties,RabbitMQ的爲RabbitProperties對象

另外咱們若是想進行嵌套的話能夠藉助於@NestedConfigurationProperty註解實現。也能夠藉助於內部類。這裏用內部類實現將開頭yaml中全部的屬性進行注入:blog

package cn.felord.yaml.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import static cn.felord.yaml.properties.FelordProperties.PREFIX;


/** * 內部類和枚舉配置. * * @author felord.cn */
@Data
@ConfigurationProperties(PREFIX)
public class FelordProperties {

    static final String PREFIX = "felord";
    private Def def;
    private Dev dev;
    private Type type;

    @Data
    public static class Def {
        private String name;
        private String blog;
        private String weChat;
    }

    @Data
    public static class Dev {
        private String name;
        private String blog;
        private String weChat;
    }

    public enum Type {
        JUEJIN,
        SF,
        OSC,
        CSDN
    }
}
複製代碼

單獨使用@ConfigurationProperties的話依然沒法直接使用配置對象FelordDefProperties,由於它並無被註冊爲Spring Bean。咱們能夠經過兩種方式來使得它生效。開發

3.1 顯式注入Spring IoC

你可使用@Component@Configuration等註解將FelordDefProperties注入Spring IoC使之生效。

package cn.felord.yaml.properties;

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

import static cn.felord.yaml.properties.FelordDefProperties.PREFIX;

/** * 顯式注入Spring IoC * @author felord.cn */
@Data
@Component
@ConfigurationProperties(PREFIX)
public class FelordDefProperties {
    static final String PREFIX = "felord.def";
    private String name;
    private String blog;
    private String weChat;
}
複製代碼

3.2 使用@EnableConfigurationProperties註冊

咱們還可使用註解@EnableConfigurationProperties進行註冊,這樣就不須要顯式聲明配置類爲Spring Bean了。

package cn.felord.yaml.configuration;

import cn.felord.yaml.properties.FelordDevProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/** * 使用 {@link EnableConfigurationProperties} 註冊 {@link FelordDevProperties}使之生效 * @author felord.cn */
@EnableConfigurationProperties({FelordDevProperties.class})
@Configuration
public class FelordConfiguration {
}
複製代碼

該註解須要顯式的註冊對應的配置類。

3.3 使用@ConfigurationPropertiesScan掃描

Spring Boot 2.2.0.RELEASE中提供了一個掃描註解@ConfigurationPropertiesScan。它能夠掃描特定包下全部的被@ConfigurationProperties標記的配置類,並將它們進行IoC注入。

package cn.felord.yaml;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

/** * {@link ConfigurationPropertiesScan} 同 {@link EnableConfigurationProperties} 二選一 * * @see cn.felord.yaml.configuration.FelordConfiguration * @author felord.cn */
@ConfigurationPropertiesScan
@SpringBootApplication
public class SpringBootYamlApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootYamlApplication.class, args);
    }

}
複製代碼

這很是適合自動注入和批量注入配置類的場景,可是有版本限制,必須在2.2.0及以上。

3.4 Environment

Spring Boot項目的話也能夠經過org.springframework.core.env.Environment 提供的getProperty(String key)來獲取,通常並非很經常使用。

4. 總結

平常開發中單個屬性推薦使用@Value,若是同一組屬性爲多個則推薦@ConfigurationProperties。須要補充一點的是@ConfigurationProperties還支持使用JSR303進行屬性校驗。多多關注:碼農小胖哥 獲取更多的技術乾貨。相關的demo 可經過公衆號回覆yaml獲取。

關注公衆號:Felordcn獲取更多資訊

我的博客:https://felord.cn

相關文章
相關標籤/搜索