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

最新文章

  1. overload、overwrite、override
  2. [LeetCode] Wiggle Sort
  3. 升级Win2010后, 打开SQL2008 附加数据库提示 5120错误
  4. 代码规范、GitHub提交源码的标准 答题人-杨宇杰
  5. Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(可持久化Trie)
  6. Wormholes
  7. English Training Material - 03
  8. 【php】使用phpdbg来调试php程序
  9. Laravel 5 基础(八)- 模型、控制器、视图基础流程
  10. hdu 1196 Lowest Bit
  11. 4k 对齐,你准备好了吗?
  12. 1003: [ZJOI2006]物流运输trans - BZOJ
  13. Javascript中setTimeout和setInterval的区别和使用
  14. CRM Entity 之Money转string int类型等
  15. Java中的流程控制(二)
  16. C#笔记(二)变量
  17. BZOJ:4209: 西瓜王
  18. Mysql--基础(一)
  19. JS实现控制HTML5背景音乐播放暂停
  20. 【Luogu4719】动态dp

热门文章

  1. Ubuntu一键安装Mariadb
  2. Copy-on-write + Proxy = ?
  3. SQL--SQL详解(DDL,DML,DQL,DCL)
  4. 如何一步步使用国内yum源一键安装openstack-ocata版本基于centos7
  5. @hdu - 6426@ Problem A.Alkane
  6. [每日一题2020.06.09] leetcode #97 交错字符串 dp
  7. JVM 之 Linux定位CPU过高问题及优化
  8. matlab中imwrite函数详解(imwrite的输出格式)
  9. C# WPF - MVVM实现OPC Client管理系统
  10. mybatis缓存之一级缓存(一)