Spring Boot 2 實(shí)戰(zhàn):常用讀取配置的方式

1. 前言

在Spring Boot項(xiàng)目中我們經(jīng)常需要讀取application.yml配置文件的自定義配置,今天就來羅列一下從yaml讀取配置文件的一些常用手段和方法。

2. 使用@Value注解

首先,會(huì)想到使用@Value注解,該注解只能去解析yaml文件中的簡(jiǎn)單類型,并綁定到對(duì)象屬性中去。

felord:
  phone: 182******32
  def:
    name: java那點(diǎn)兒事
    blog: felord.cn
    we-chat: MSW_623
  dev:
    name: java那點(diǎn)兒事
    blog: felord.cn
    we-chat: MSW_623
  type: JUEJIN  

對(duì)于上面的yaml配置,如果我們使用@Value注解的話,冒號(hào)后面直接有值的key才能正確注入對(duì)應(yīng)的值。例如felord.phone我們可以通過@Value獲取,但是felord.def不行,因?yàn)閒elord.def后面沒有直接的值,它還有下一級(jí)選項(xiàng)。另外@Value不支持yaml松散綁定語(yǔ)法,也就是說felord.def.weChat獲取不到felord.def.we-chat的值。

@Value是通過使用Spring的SpEL表達(dá)式來獲取對(duì)應(yīng)的值的:

// 獲取 yaml 中 felord.phone的值 并提供默認(rèn)值 UNKNOWN
@Value("${felord.phone:UNKNOWN}")
 private String phone;

@Value的使用場(chǎng)景是只需要獲取配置文件中的某項(xiàng)值的情況下,如果我們需要將一個(gè)系列的值進(jìn)行綁定注入就建議使用復(fù)雜對(duì)象的形式進(jìn)行注入了。

3. 使用@ConfigurationProperties注解

@ConfigurationProperties注解提供了我們將多個(gè)配置選項(xiàng)注入復(fù)雜對(duì)象的能力。它要求我們指定配置的共同前綴。比如我們要綁定felord.def下的所有配置項(xiàng):

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的值,因?yàn)檫@種形式支持從駝峰camel-case到短橫分隔命名kebab-case的自動(dòng)轉(zhuǎn)換。

如果我們使用@ConfigurationProperties的話建議配置類命名后綴為Properties,比如Redis的后綴就是RedisProperties,RabbitMQ的為RabbitProperties。

另外我們?nèi)绻脒M(jìn)行嵌套的話可以借助于@NestedConfigurationProperty注解實(shí)現(xiàn)。也可以借助于內(nèi)部類。這里用內(nèi)部類實(shí)現(xiàn)將開頭yaml中所有的屬性進(jìn)行注入:

package cn.felord.yaml.properties;

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

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


/**
 * 內(nèi)部類和枚舉配置.
 *
 * @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
    }
}

單獨(dú)使用@ConfigurationProperties的話依然無法直接使用配置對(duì)象FelordDefProperties,因?yàn)樗]有被注冊(cè)為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注冊(cè)

我們還可以使用注解@EnableConfigurationProperties進(jìn)行注冊(cè),這樣就不需要顯式聲明配置類為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} 注冊(cè) {@link FelordDevProperties}使之生效
 * @author felord.cn
 */
@EnableConfigurationProperties({FelordDevProperties.class})
@Configuration
public class FelordConfiguration {
}

該注解需要顯式的注冊(cè)對(duì)應(yīng)的配置類。

3.3 使用@ConfigurationPropertiesScan掃描

在Spring Boot 2.2.0.RELEASE中提供了一個(gè)掃描注解@ConfigurationPropertiesScan。它可以掃描特定包下所有的被@ConfigurationProperties標(biāo)記的配置類,并將它們進(jìn)行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);
    }

}

這非常適合自動(dòng)注入和批量注入配置類的場(chǎng)景,但是有版本限制,必須在2.2.0及以上。

3.4 Environment

Spring Boot項(xiàng)目的話也可以通過org.springframework.core.env.Environment 提供的getProperty(String key)來獲取,一般并不是很常用。

4. 總結(jié)

日常開發(fā)中單個(gè)屬性推薦使用@Value,如果同一組屬性為多個(gè)則推薦@ConfigurationProperties。需要補(bǔ)充一點(diǎn)的是@ConfigurationProperties還支持使用JSR303進(jìn)行屬性校驗(yàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Boot獲取文件總的來說有三種方式,分別是@Value注解,@ConfigurationProper...
    java那點(diǎn)兒事閱讀 263評(píng)論 0 0
  • 第一次書寫簡(jiǎn)書。。。不知道排版和頁(yè)面會(huì)不會(huì)好看。唉,湊活來吧。開干。 本文會(huì)分享三種讀取配置文件的方式: 1....
    西貝勒HalJia閱讀 1,343評(píng)論 0 0
  • Spring Boot獲取文件總的來說有三種方式,分別是@Value注解,@ConfigurationProper...
    Java旅途閱讀 140評(píng)論 0 0
  • 久違的晴天,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了。班主任說已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,818評(píng)論 16 22
  • 創(chuàng)業(yè)是很多人的夢(mèng)想,多少人為了理想和不甘選擇了創(chuàng)業(yè)來實(shí)現(xiàn)自我價(jià)值,我就是其中一個(gè)。 創(chuàng)業(yè)后,我由女人變成了超人,什...
    亦寶寶閱讀 2,005評(píng)論 4 1

友情鏈接更多精彩內(nèi)容