SpringBoot读取配置文件的几种方式
Spring读取配置文件的几种方法,SpringBoot也都支持。具体查看:https://www.cnblogs.com/myitnews/p/14028588.html
本文主要介绍SpringBoot独有的一种读取方法,使用注解:@ConfigurationProperties。
使用 @Value 注解或者使用 Spring Environment bean 访问这些属性,是这种注入配置方式有时显得很笨重。使用@ConfigurationProperties )来获取这些属性会更灵活。
@ConfigurationProperties 的基本用法非常简单:为每个要捕获的外部属性提供一个带有字段的类。请注意以下几点:
- 前缀定义了哪些外部属性将绑定到类的字段上
- 根据 Spring Boot 宽松的绑定规则,类的属性名称必须与外部属性的名称匹配
- 我们可以简单地用一个值初始化一个字段来定义一个默认值
- 类本身可以是包私有的
- 类的字段必须有公共 setter 方法
Spring 宽松绑定规则 (relaxed binding)
Spring使用一些宽松的绑定属性规则。因此,以下变体都将绑定到 hostName 属性上:
mail.hostName=localhost
mail.hostname=localhost
mail.host_name=localhost
mail.host-name=localhost
mail.HOST_NAME=localhost
一、激活@ConfigurationProperties
- 添加@Component等注组件注解
- 通过 Spring 的 Java Configuration 特性实现(@Bena)。
- 使用@EnableConfigurationProperties 注解
- 该注解中其实是用了@Import(EnableConfigurationPropertiesImportSelector.class) 实现(不推荐)。
二、无法转换的属性和未知的属性
无法转换的属性
如果我们在 application.properties 属性上定义的属性不能被正确的解析会发生什么?默认情况下,Spring Boot 将会启动失败,并抛出异常。
当我们为属性配置错误的值时,而又不希望 Spring Boot 应用启动失败,我们可以设置 ignoreInvalidFields 属性为 true (默认为 false)。
未知的属性
如果我们在 application.properties 文件提供了 MailModuleProperties 类不知道的属性会发生什么?
默认情况下,Spring Boot 会忽略那些不能绑定到 @ConfigurationProperties 类字段的属性。
然而,当配置文件中有一个属性实际上没有绑定到 @ConfigurationProperties 类时,我们可能希望启动失败。也许我们以前使用过这个配置属性,但是它已经被删除了,这种情况我们希望被触发告知手动从 application.properties 删除这个属性。
为了实现上述情况,我们仅需要将 ignoreUnknownFields 属性设置为 false (默认是 true)。
弃用警告⚠️(Deprecation Warning)
ignoreUnknownFields 在未来 Spring Boot 的版本中会被标记为 deprecated,因为我们可能有两个带有 @ConfigurationProperties 的类,同时绑定到了同一个命名空间 (namespace) 上,其中一个类可能知道某个属性,另一个类却不知道某个属性,这样就会导致启动失败
三、启动时校验 @ConfigurationProperties
如果我们希望配置参数在传入到应用中时有效的,我们可以通过在字段上添加 bean validation 注解,同时在类上添加 @Validated 注解。
应用启动时,我们将会得到 BindValidationException。
当然这些默认的验证注解不能满足你的验证要求,我们也可以自定义注解。
如果你的验证逻辑很特殊,我们可以实现一个方法,并用 @PostConstruct 标记,如果验证失败,方法抛出异常即可。
四、复杂属性类型
多数情况,我们传递给应用的参数是基本的字符串或数字。但是,有时我们需要传递诸如 List 的数据类型。
List 和 Set
我们有两种方式让 Spring Boot 自动填充该 list 属性。
(1) application.properties
在 application.properties 文件中以数组形式书写:
(2) application.yml
YAML 本身支持 list 类型,所以可以在 application.yml 文件中添加:
set 集合也是这种方式的配置方式,不再重复书写。另外YAML 是更好的阅读方式,层次分明,所以在实际应用中更推荐大家使用该种方式做数据配置。
Map<String, String>
SpringBoot也支持Map<String,String>的读取。
1、application.properties配置如下:
fyk.db-script.check-sql.[1-FYK_PROPERTIES-DQL]=select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual fyk.db-script.check-sql.[2-FYK_PROPERTIES-DML-fyk-oauth]=select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual
注意:如果Map类型的key包含非字母数字和-的字符,需要用[]括起来,否则不需要使用中括号。
2、配置类读取如下:
@Component @ConfigurationProperties(prefix = "fyk.db-script") public class CheckSqlProperties { private Map<String, String> checkSql; public Map<String, String> getCheckSql() { return checkSql; } public void setCheckSql(Map<String, String> checkSql) { this.checkSql = checkSql; } }
3、扩展:使用@Value的方式获取
要使用@Value的方式获取,首先配置文件中,配置的方式要改下,如下:
fyk.db-script.check-sql={\ "1-FYK_PROPERTIES-DQL":"select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual",\ "2-FYK_PROPERTIES-DML-fyk-oauth":"select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual"\ }
注意:如果Map类型的key包含非字母数字和-的字符,需要用引号括起来,否则不需要使用引号(建议都用上引号);value值,都必须要用引号括起来。
在使用该配置的地方,使用@Value的使用获取:
@Value("#{${fyk.db-script.check-sql}}") private Map<String, String> checkSql
Duration
Spring Boot 内置支持从配置参数中解析 durations (持续时间)。
我们既可以配置毫秒数数值,也可配置带有单位的文本。
配置 duration 不写单位,默认按照毫秒来指定,我们也可已通过 @DurationUnit 来指定单位。
常用单位如下:
ns
for nanoseconds (纳秒)us
for microseconds (微秒)ms
for milliseconds (毫秒)s
for seconds (秒)m
for minutes (分)h
for hours (时)d
for days (天)
DataSize
与 Duration 的用法一样,默认单位是 byte (字节),可以通过 @DataSizeUnit 单位指定。
添加配置
但是,我测试的时候打印出来结果都是以 B (bytes) 来显示
常见单位如下:
B
for bytesKB
for kilobytesMB
for megabytesGB
for gigabytesTB
for terabytes
自定义类型
有些情况,我们想解析配置参数到我们自定义的对象类型上,假设,我们我们设置最大包裹重量:
在 MailModuleProperties 中添加 Weight 属性
我们可以模仿 DataSize 和 Duration 创造自己的 converter (转换器)
将其注册到 Spring Boot 上下文中
@ConfigurationPropertiesBinding 注解是让 Spring Boot 知道使用该转换器做数据绑定。
五、使用 Spring Boot Configuration Processor 完成自动补全
添加依赖:
重新 build 项目之后,configuration processor 会为我们创建一个 JSON 文件:
这样,当我们在 application.properties 和 application.yml 中写配置的时候会有自动提醒。
六、标记配置属性为 Deprecated
configuration processor 允许我们标记某一个属性为 deprecated
我们可以通过添加 @DeprecatedConfigurationProperty 注解到字段的 getter 方法上,来标示该字段为 deprecated,重新 build 项目,看看 JSON 文件发生了什么?
当我们再编写配置文件时,已经给出了明确 deprecated 提示:
七、总结
Spring Boot 的 @ConfigurationProperties 注解在绑定类型安全的 Java Bean 时是非常强大的,我们可以配合其注解属性和 @DeprecatedConfigurationProperty 注解获取到更友好的编程方式,同时这样让我们的配置更加模块化。
注意:如果使用 SpEL 表达式,我们只能选择 @Value 注解。
转自:https://www.cnblogs.com/jimoer/p/11374229.html