SpringBoot读取配置文件的几种方式

摘要:
类的属性名称必须与外部属性的名称匹配。我们可以简单地使用值来初始化字段以定义默认值。类本身可以是包私有类。字段必须具有公共setter方法。Spring使用一些松散的绑定属性规则。2、 如果application.properties属性上定义的属性无法正确解析为无法转换的属性和无法转换的未知属性,会发生什么?

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 的数据类型。

SpringBoot读取配置文件的几种方式第1张

List 和 Set

我们有两种方式让 Spring Boot 自动填充该 list 属性。

(1) application.properties

在 application.properties 文件中以数组形式书写:

SpringBoot读取配置文件的几种方式第2张

(2) application.yml

YAML 本身支持 list 类型,所以可以在 application.yml 文件中添加:

SpringBoot读取配置文件的几种方式第3张

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 (持续时间)。

SpringBoot读取配置文件的几种方式第4张

我们既可以配置毫秒数数值,也可配置带有单位的文本。

SpringBoot读取配置文件的几种方式第5张

配置 duration 不写单位,默认按照毫秒来指定,我们也可已通过 @DurationUnit 来指定单位。

SpringBoot读取配置文件的几种方式第6张

常用单位如下:

  • 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 单位指定。

SpringBoot读取配置文件的几种方式第7张

添加配置

SpringBoot读取配置文件的几种方式第8张

但是,我测试的时候打印出来结果都是以 B (bytes) 来显示

常见单位如下:

  • B for bytes
  • KB for kilobytes
  • MB for megabytes
  • GB for gigabytes
  • TB for terabytes
自定义类型

有些情况,我们想解析配置参数到我们自定义的对象类型上,假设,我们我们设置最大包裹重量:

SpringBoot读取配置文件的几种方式第9张

在 MailModuleProperties 中添加 Weight 属性

SpringBoot读取配置文件的几种方式第10张

我们可以模仿 DataSize 和 Duration 创造自己的 converter (转换器)

SpringBoot读取配置文件的几种方式第11张

将其注册到 Spring Boot 上下文中

SpringBoot读取配置文件的几种方式第12张

@ConfigurationPropertiesBinding 注解是让 Spring Boot 知道使用该转换器做数据绑定。

五、使用 Spring Boot Configuration Processor 完成自动补全

添加依赖:

SpringBoot读取配置文件的几种方式第13张

重新 build 项目之后,configuration processor 会为我们创建一个 JSON 文件:

SpringBoot读取配置文件的几种方式第14张

这样,当我们在 application.properties 和 application.yml 中写配置的时候会有自动提醒。

SpringBoot读取配置文件的几种方式第15张

六、标记配置属性为 Deprecated

configuration processor 允许我们标记某一个属性为 deprecated

SpringBoot读取配置文件的几种方式第16张

我们可以通过添加 @DeprecatedConfigurationProperty 注解到字段的 getter 方法上,来标示该字段为 deprecated,重新 build 项目,看看 JSON 文件发生了什么?

SpringBoot读取配置文件的几种方式第17张

当我们再编写配置文件时,已经给出了明确 deprecated 提示:

SpringBoot读取配置文件的几种方式第18张

七、总结

Spring Boot 的 @ConfigurationProperties 注解在绑定类型安全的 Java Bean 时是非常强大的,我们可以配合其注解属性和 @DeprecatedConfigurationProperty 注解获取到更友好的编程方式,同时这样让我们的配置更加模块化。

注意:如果使用 SpEL 表达式,我们只能选择 @Value 注解。

转自:https://www.cnblogs.com/jimoer/p/11374229.html

免责声明:文章转载自《SpringBoot读取配置文件的几种方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Aurora 极光 A21超算将会使用SPR CPU和Ponte Vecchio GPU利用基于Go Lang的Hugo配合nginx来打造属于自己的纯静态博客系统下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ODBC 连接 Oracle 11g 详细步骤

  Oracle 11g 客户端连接1 安装对应的程序,完全安装(要安装和Oracle对应的版本,要不然ODBC进程会出现奇怪的问题,在部署环境中也是一样)2 在开始菜单中找到安装的Oracle 文件夹,之后在配置和移植工具->Net Configuration Assistant->本地网络名配置->添加配置文件示例:Data Sou...

CSS定位(postion)和移动(float)

5、定位和移动:Positioning(定位)CSS定位属性允许你为一个元素定位。它也可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么。元素可以使用的顶部,底部,左侧和右侧属性定位。然而,这些属性无法工作,除非是先设定position属性。他们也有不同的工作方式,这取决于定位方法.有四种不同的定位方法。Static 定位HTML元...

WPF下的右键菜单隐藏

WPF中,右键菜单一旦设置,就很难控制其不让打开,点击右键一定会弹出,如果只是隐藏几个项还是没问题的,但是如果所有项都隐藏了,还是会弹出一个空白内容的右键菜单,难看死,也没有给任何后台控制的方法,于是找到了一个前台的属性可以控制。 <Window x:Class="WPFTest.Window1" xmlns="http://sche...

Web前端开发最佳实践(9):CSS代码太太乱,重复代码太多?你需要精简CSS代码

前言 提高网站整体加载速度的一个重要手段就是提高代码文件的网络传输速度。之前提到过,所有的代码文件都应该是经过压缩了的,这可提高网络传输速度,提高性能。除了压缩代码之外,精简代码也是一种减小代码文件大小的手段。以下将讨论CSS代码相关的代码精简方案。 定义简洁的CSS规则 CSS的每条规则中都包含了规则的属性及属性值。定义简洁的CSS规则主要是指合并相关规...

.NET Core分布式事件总线、分布式事务解决方案:CAP

简介 CAP 是一个遵循 .NET Standard 标准库的C#库,用来处理分布式事务以及提供EventBus的功能,它具有轻量级,高性能,易使用等特点。 分布式事务是在分布式系统中不可避免的一个硬性需求,CAP 没有采用两阶段提交(2PC)这种事务机制,而是采用的 本地消息表+MQ 这种经典的实现方式,这种方式又叫做 异步确保。 CAP 实现了 Eve...

【基础知识】winfrom窗体的属性

窗体的属性: Icon:窗体的右上角图标 FormBoarderStyle:窗体的边线样式 MaximizeBox: 最大化按钮是否可用 MinimizeBox:最小化按钮是否可用 Opacity:透明度 ShowInTaskbar:是否在任务栏上显示 StartPosition:启动程序时显示的位置 Text:标题栏的名称 TopMost:保持在最前端,...