乐趣区

Spring-Boot-2-实战常用读取配置的方式

1. 前言

Spring Boot 我的项目中咱们常常须要读取 application.yml 配置文件的自定义配置,明天就来列举一下从 yaml 读取配置文件的一些罕用伎俩和办法。

2. 应用 @Value 注解

首先,会想到应用 @Value 注解,该注解只能去解析 yaml 文件中的简略类型,并绑定到对象属性中去。

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 的值。

@Value是通过应用 SpringSpEL表达式来获取对应的值的:

// 获取 yaml 中 felord.phone 的值 并提供默认值 UNKNOWN
@Value("${felord.phone:UNKNOWN}")
 private String phone;

@Value的应用场景是只须要获取配置文件中的某项值的状况下,如果咱们须要将一个系列的值进行绑定注入就倡议应用简单对象的模式进行注入了。

3. 应用 @ConfigurationProperties 注解

@ConfigurationProperties注解提供了咱们将多个配置选项注入简单对象的能力。它要求咱们指定配置的独特前缀。比方咱们要绑定 felord.def 下的所有配置项:

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 的主动转换。

如果咱们应用 @ConfigurationProperties 的话倡议配置类命名后缀为 Properties,比方Redis 的后缀就是 RedisProperties,RabbitMQ 的为RabbitProperties

另外咱们如果想进行嵌套的话能够借助于 @NestedConfigurationProperty 注解实现。也能够借助于外部类。这里用外部类实现将结尾 yaml 中所有的属性进行注入:

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

退出移动版