SpringBoot @ConfigurationProperties详解

简介

本文将会详细讲解@ConfigurationProperties在Spring Boot中的使用。

添加依赖关系

首先我们需要添加Spring Boot依赖:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<relativePath/> <!-- lookup parent from repository -->
</parent>

一个简单的例子

@ConfigurationProperties需要和@Configuration配合使用,我们通常在一个POJO里面进行配置:

@Data
@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties { private String hostName;
private int port;
private String from;
}

上面的例子将会读取properties文件中所有以mail开头的属性,并和bean中的字段进行匹配:

#Simple properties
mail.hostname=host@mail.com
mail.port=9000
mail.from=mailer@mail.com

Spring的属性名字匹配支持很多格式,如下所示所有的格式都可以和hostName进行匹配:

mail.hostName
mail.hostname
mail.host_name
mail.host-name
mail.HOST_NAME

如果你不想使用@Configuration, 那么需要在@EnableConfigurationProperties注解中手动导入配置文件如下:

@SpringBootApplication
@EnableConfigurationProperties(ConfigProperties.class)
public class ConfigPropApp {
public static void main(String[] args) {
SpringApplication.run(ConfigPropApp.class,args);
}
}

我们也可以在@ConfigurationPropertiesScan中指定Config文件的路径:

@SpringBootApplication
@ConfigurationPropertiesScan("com.flydean.config")
public class ConfigPropApp {
public static void main(String[] args) {
SpringApplication.run(ConfigPropApp.class,args);
}
}

这样的话程序只会在com.flydean.config包中查找config文件。

属性嵌套

我们可以嵌套class,list,map, 下面我们举个例子,先创建一个普通的POJO:

@Data
public class Credentials {
private String authMethod;
private String username;
private String password;
}

然后创建一个嵌套的配置文件:

@Data
@Configuration
@ConfigurationProperties(prefix = "nestmail")
public class NestConfigProperties {
private String host;
private int port;
private String from;
private List<String> defaultRecipients;
private Map<String, String> additionalHeaders;
private Credentials credentials;
}

对应的属性文件如下:

# nest Simple properties
nestmail.hostname=mailer@mail.com
nestmail.port=9000
nestmail.from=mailer@mail.com #List properties
nestmail.defaultRecipients[0]=admin@mail.com
nestmail.defaultRecipients[1]=owner@mail.com #Map Properties
nestmail.additionalHeaders.redelivery=true
nestmail.additionalHeaders.secure=true #Object properties
nestmail.credentials.username=john
nestmail.credentials.password=password
nestmail.credentials.authMethod=SHA1

@ConfigurationProperties和@Bean

@ConfigurationProperties也可以和@Bean一起使用如下所示:

@Data
public class Item {
private String name;
private int size;
}

看下怎么使用:

@Data
@Configuration
public class BeanConfigProperties {
@Bean
@ConfigurationProperties(prefix = "item")
public Item item() {
return new Item();
}
}

属性验证

@ConfigurationProperties可以使用标准的JSR-303格式来做属性验证。我们举个例子:

@Data
@Validated
@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties { @NotEmpty
private String hostName;
@Min(1025)
@Max(65536)
private int port;
@Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$")
private String from;
}

如果我们的属性不满足上诉条件,可能出现如下异常:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'mail' to com.flydean.config.ConfigProperties$$EnhancerBySpringCGLIB$$f0f87cb9 failed:

    Property: mail.port
Value: 0
Reason: 最小不能小于1025 Property: mail.hostName
Value: null
Reason: 不能为空 Action: Update your application's configuration Process finished with exit code 1

属性转换

@ConfigurationProperties也支持多种属性转换,下面我们以Duration和DataSize为例:

我们定义两个Duration的字段:

@ConfigurationProperties(prefix = "conversion")
public class PropertyConversion { private Duration timeInDefaultUnit;
private Duration timeInNano;
...
}

在属性文件中定义这两个字段:

conversion.timeInDefaultUnit=10
conversion.timeInNano=9ns

我们看到上面的属性可以带单位的。可选的单位是:ns, us, ms, s, m, h 和 d,分别对应纳秒,微妙,毫秒,秒,分钟,小时和天。默认单位是毫秒。我们也可以在注解中指定单位:

@DurationUnit(ChronoUnit.DAYS)
private Duration timeInDays;

对应的配置文件如下:

conversion.timeInDays=2

下面我们再看看DataSize怎么使用:

private DataSize sizeInDefaultUnit;

private DataSize sizeInGB;

@DataSizeUnit(DataUnit.TERABYTES)
private DataSize sizeInTB;

对应的属性文件:

conversion.sizeInDefaultUnit=300
conversion.sizeInGB=2GB
conversion.sizeInTB=4

Datasize支持B, KB, MB, GB 和TB。

自定义Converter

同样的Spring Boot也支持自定义属性转换器。我们先定义一个POJO类:

public class Employee {
private String name;
private double salary;
}

对应的属性文件:

conversion.employee=john,2000

我们需要自己实现一个Converter接口的转换类:

@Component
@ConfigurationPropertiesBinding
public class EmployeeConverter implements Converter<String, Employee> { @Override
public Employee convert(String from) {
String[] data = from.split(",");
return new Employee(data[0], Double.parseDouble(data[1]));
}
}

本文的例子可以参看: https://github.com/ddean2009/learn-springboot2/tree/master/springboot-ConfigurationProperties

更多教程请参考 flydean的博客

SpringBoot @ConfigurationProperties详解的更多相关文章

  1. springboot配置详解

    springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...

  2. springboot项目--传入参数校验-----SpringBoot开发详解(五)--Controller接收参数以及参数校验----https://blog.csdn.net/qq_31001665/article/details/71075743

    https://blog.csdn.net/qq_31001665/article/details/71075743 springboot项目--传入参数校验-----SpringBoot开发详解(五 ...

  3. Spring Boot2 系列教程 (二) | 第一个 SpringBoot 工程详解

    微信公众号:一个优秀的废人 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 哎呦喂,按照以往的惯例今天周六我的安排应该是待在家学学猫叫啥的.但是今年这种日子就可能一去不复返了,没法办法啊.前 ...

  4. SpringBoot 配置文件详解

    springboot采纳了建立生产就绪spring应用程序的观点. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.在一般情况下,我们不需要做太多的配置就能够让spring boot正 ...

  5. SpringBoot | 第三章:springboot配置详解

    基于springboot的约定优于配置的原则,在多数情况下,启动一个应用时,基本上无需做太多的配置,应用就能正常启动.但在大部分开发环境下,添加额外配置是无所避免的,比如自定义应用端口号(比较在机器比 ...

  6. 第二篇:SpringBoot配置详解

    SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖 ...

  7. SpringBoot——配置文件详解【五】

    前言 SpringBoot的配置文件 配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的. application.properties application.yml 配置文件 ...

  8. Springboot 启动详解

    1.前言 最近一直在看Springboot和springcloud代码,看了将近20多天,对这两个系统的认知总算是入了门.后续应该会有一个系列的文章,本文就先从Springboot的启动入手. 2.容 ...

  9. 2.SpringBoot HelloWorld详解

    1.POM文件 父项目 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...

随机推荐

  1. CSS躬行记(3)——CSS属性拾遗

    一.粘滞定位 粘滞定位(sticky)与相对定位类似,既不会脱离正常流,也不会改变元素盒类型,并且会保留原先所占的空间.它会相对于包含块偏移,它的包含块分为两种,第一种和绝对定位一样:第二种是最近的滚 ...

  2. 面试官:JavaScript 原始数据类型 Symbol 有什么用?

    以前提到 JavaScript 原始数据类型时,我们知道有Number,String,Null,Boolean,Undefined这几种.ES6 引入了新的基本数据类型Symbol和BigInt.今天 ...

  3. 2020年Java多线程与并发系列22道高频面试题(附思维导图和答案解析)

    前言 现在不管是大公司还是小公司,去面试都会问到多线程与并发编程的知识,大家面试的时候这方面的知识一定要提前做好储备. 关于多线程与并发的知识总结了一个思维导图,分享给大家 1.Java中实现多线程有 ...

  4. Vue学习(1)---Vue介绍

    Vue是什么 官方定义:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层 ...

  5. Spring 中使用 ActiveMQ 笔记

    首先需要在 pom.xml 中添加如下两个 jar 包:spring-jms 与 activemq-core,其依赖的 jar 包会自动下载 接着进行相关配置 @Configuration publi ...

  6. Linux基础篇,文本数据的比较与排序:sort、uniq、comm、diff

    一.sort sort命令用于将文本文件内容以行排序 sort [选项参数] [-o<输出文件>] [-t<分隔字符>] [+<起始栏位> -<结束栏位> ...

  7. char类型及ASCII码之间比较

    在JAVA中,char类型可以直接运算,char在ASCII等字符编码表中有对应的数值对char类型字符运行时,直接当做ASCII表对应的整数来对待 参考 https://blog.csdn.net/ ...

  8. CVE-2019-0232 远程代码执行漏洞-复现

    0x00 漏洞介绍 该漏洞是由于Tomcat CGI将命令行参数传递给Windows程序的方式存在错误,使得CGIServlet被命令注入影响. 该漏洞只影响Windows平台,要求启用了CGISer ...

  9. Pytest系列(23)- allure打标记,@allure.feature()、@allure.story()、@allure.severity()的详细使用

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 前面几篇文章主要介绍了all ...

  10. Python-selenium 元素定位

    1.id定位find_element_by_id() 通过id属性定位元素,如果id是动态变化的话不能用id来进行定位 2.name定位find_element_by_name() 通过name属性定 ...