使用 @Value("${property}") 注释注入配置属性有时会很麻烦,尤其是当你使用多个属性或你的数据是分层的时候。

Spring Boot 引入了一个可替换的方案 —— @ConfigurationProperties 来注入属性。

JavaBean 属性绑定

@Data
@ConfigurationProperties("my.service")
public class MyProperties { // 我们可以简单地用一个值初始化一个字段来定义一个默认值
private boolean enabled = true; private InetAddress remoteAddress; private final Security security = new Security(); @Data
public static class Security { private String username; private String password;
// 如果这个属性配置的话,默认是“USER”
private List<String> roles = new ArrayList<>(Collections.singleton("USER")); }
}

在配置文件中进行如下配置:

my:
service:
enabled: true
remoteAddress: 127.0.0.1
security:
username: csx
password: passwoed
roles:
- role1
- role2

最后生成的 Bean 的属性如下:

{
"enabled": true,
"remoteAddress": "127.0.0.1",
"security": {
"username": "csx",
"password": "passwoed",
"roles": [
"role1",
"role2"
]
}
}

以上的绑定当时需要提供默认的构造函数,以及get/setter方法。

并且不支持 JavaBean 中的静态成员变量的数据绑定

另外,@ConfigurationProperties 还有两个其他属性。

@ConfigurationProperties( value = "my.service",
ignoreInvalidFields = false,
ignoreUnknownFields = false)

ignoreInvalidFields:是否忽略非法值,比如将一个字符串 “foo” 赋值给 bool 值,不忽略的话会报启动异常。

ignoreUnknownFields:对于多余的配置是否会报异常。

构造函数绑定

有些情况下,我们需要绑定的 JavaBean 是不可变的(防止配置注入 Bean 以后,开发者在程序中错误地将配置改掉了)。这种情况下我们可以使用构造函数形式的绑定,只提供 getter 方法。

@Getter
@ConstructorBinding
@ConfigurationProperties("my.service")
public class MyProperties { private boolean enabled;
private InetAddress remoteAddress;
private final Security security; public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) {
this.enabled = enabled;
this.remoteAddress = remoteAddress;
this.security = security;
} @Getter
public static class Security { private String username;
private String password;
private List<String> roles; public Security(String username, String password, @DefaultValue("USER") List<String> roles) {
this.username = username;
this.password = password;
this.roles = roles;
}
}
}

@DefaultValue 可以指定默认值。

使用构造函数绑定的方式,只能 @EnableConfigurationProperties 或者 @ConfigurationPropertiesScan 的方式激活 Bean。而不能使用 @Component、@Bean 或者 @Import 的方式进行数据绑定。

如果你的类有多个构造函数,可以直接指定使用哪个。

@ConstructorBinding
public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) {
this.enabled = enabled;
this.remoteAddress = remoteAddress;
this.security = security;
}

激活方式

方式一:添加 @Component 注解

上面的方式需要保证 MyProperties 能被 Spring 扫到。

@Data
@Component
@ConfigurationProperties("my.service")
public class MyProperties { }

方式二:通过 @Bean 方法

@Configuration
public class ServiceConfig { @Bean
public MyProperties myProperties(){
return new MyProperties();
}
}

方式三:@EnableConfigurationProperties(推荐)

@Configuration
@EnableConfigurationProperties(MyProperties.class)
public class ServiceConfig { }

方式四:@ConfigurationPropertiesScan

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "com.example.another" })
public class MyApplication { }

怎么使用

我们通过配置在 Spring 容器中生成了配置 Bean,那么需要怎么使用他们呢?

@Service
public class MyService {
// 依赖注入
@Autowired
private MyProperties properties; public void service(){
System.out.println(properties.getRemoteAddress());
} } @Service
public class MyService { private MyProperties properties;
// 通过构造函数注入,一般推荐这种方式
public MyService(MyProperties properties) {
this.properties = properties;
} public void service(){
System.out.println(properties.getRemoteAddress());
} }

给第三方类绑定值

假如某些类不是你自己开发的,你也想使用 @ConfigurationProperties 的方式给他绑定值,那么可以进行下面的方式进行配置。

@Configuration(proxyBeanMethods = false)
public class ThirdPartyConfiguration { @Bean
@ConfigurationProperties(prefix = "another")
public AnotherComponent anotherComponent() {
return new AnotherComponent();
} }

宽松绑定原则(Relaxed Binding)

所谓的宽松绑定原则是指:并不是 JavaBean 中的属性必须要和配置文件中的一致才能绑定数据,context-path 也能绑定到 contextPath 属性上。下面举个列子:

@ConfigurationProperties(prefix = "my.main-project.person")
public class MyPersonProperties { private String firstName; public String getFirstName() {
return this.firstName;
} public void setFirstName(String firstName) {
this.firstName = firstName;
} }

下面的几种方式,都能将配置文件或者环境变量中的值绑定到 firstName 上。

形式 使用场景
my.main-project.person.first-name 推荐使用在 .properties and .yml files.
my.main-project.person.firstName Standard camel case syntax.
my.main-project.person.first_name 推荐使用在 .properties and .yml files.
MY_MAINPROJECT_PERSON_FIRSTNAME 推荐使用在系统环境变量读取配置时使用

和 @Value 对比

@Value 是 Spring Framework 中的注解,而 @ConfigurationProperties 是在 Spring Boot 中引入的。

参考

利用 Spring Boot 中的 @ConfigurationProperties,优雅绑定配置参数的更多相关文章

  1. Spring Boot中注解@ConfigurationProperties

    在Spring Boot中注解@ConfigurationProperties有三种使用场景,而通常情况下我们使用的最多的只是其中的一种场景.本篇文章带大家了解一下三种场景的使用情况. 场景一 使用@ ...

  2. Spring Boot中只能有一个WebMvcConfigurationSupport配置类

    首先将结论写文章的最前面,一个项目中只能有一个继承WebMvcConfigurationSupport的@Configuration类(使用@EnableMvc效果相同),如果存在多个这样的类,只有一 ...

  3. 在Spring Boot中使用 @ConfigurationProperties 注解

    但 Spring Boot 提供了另一种方式 ,能够根据类型校验和管理application中的bean. 这里会介绍如何使用@ConfigurationProperties.继续使用mail做例子. ...

  4. 在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties

    但 Spring Boot 提供了另一种方式 ,能够根据类型校验和管理application中的bean. 这里会介绍如何使用@ConfigurationProperties.继续使用mail做例子. ...

  5. Spring Boot 中 Druid 的监控页面配置

    Druid的性能相比HikariCp等其他数据库连接池有一定的差距,但是数据库的相关属性的监控,别的连接池可能还追不上,如图: 今天写一下 Spring Boot 中监控页面的配置,我是直接将seat ...

  6. 曹工谈Spring Boot:Spring boot中怎么进行外部化配置,一不留神摔一跤;一路debug,原来是我太年轻了

    spring boot中怎么进行外部化配置,一不留神摔一跤:一路debug,原来是我太年轻了 背景 我们公司这边,目前都是spring boot项目,没有引入spring cloud config,也 ...

  7. Spring Boot 中使用 @ConfigurationProperties 注解

    @ConfigurationProperties 主要作用:绑定 application.properties 中的属性 例如: @Configuration public class DataSou ...

  8. 在Spring Boot中使用 @ConfigurationProperties 注解 (二十六)

    @ConfigurationProperties主要作用:就是绑定application.properties中的属性 java代码 @Configuration public class DataS ...

  9. 在Spring Boot中使用数据缓存

    春节就要到了,在回家之前要赶快把今年欠下的技术债还清.so,今天继续.Spring Boot前面已经预热了n篇博客了,今天我们来继续看如何在Spring Boot中解决数据缓存问题.本篇博客是以初识在 ...

随机推荐

  1. Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)

    大家好!我是小富- 这几天公司在排查内部数据账号泄漏,原因是发现某些实习生小可爱居然连带着账号.密码将源码私传到GitHub上,导致核心数据外漏,孩子还是没挨过社会毒打,这种事的后果可大可小. 说起这 ...

  2. noip模拟22[d·e·f]

    noip模拟22 solutions 哈哈哈,这次暴力打满直接190,其实不到哈哈哈,187.. 这次的题暴力极其好打,但是正解确实不简单... 打了好久才改完这个题,改完的时候爽暴了 这些一个字母的 ...

  3. 进入mysql的学习>从零开始学JAVA系列

    目录 MySQL的学习 什么是MYSQL 安装MYSQL Window安装MYSQL(压缩包版) 什么是MYSQL 安装MYSQL Window安装MYSQL(压缩包版) MYSQL基本指令 DDL ...

  4. 记录一次mysql的安装之旅

    mysql作为日常开发中常用到的数据库,对每个程序员来说至关重要,今天就跟着我来进行一次mysql的安装之旅吧. 一.安装 1.安装包的方式 1.1.获取安装包 对mysql有过接触的人来说,都知道m ...

  5. Manage sshd Service on CentOS

    Check the current sshd status: service sshd status Start sshd service: service sshd start Set sshd a ...

  6. 绿色djvu阅读软件

    官方的djvu viewer都需要安装,总算找到一个绿色版的,名为STDU Viewer,可以阅读的格式包括DjVu, PDF, TIFF, XPS, FB2等,版本为1.6.2.

  7. PXE高效批量装机

    目录 一.PXE概述 二.PXE的优点 三.搭建PXE的前提 四.搭建PXE远程安装服务器 4.1.安装并启用TFTP服务 4.2.安装dhcp服务 4.3.准备linux内核.初始化镜像文件 4.3 ...

  8. miniFTP项目实战五

    项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...

  9. STM32—驱动HC-SR04超声波测距模块

    文章目录 超声波测距原理 HC-SR04工作原理 STM32实现驱动 1.引脚的配置 2.时序控制 3.时间差测量 4.如何将距离测出来 超声波测距原理 利用HC-SR04超声波测距模块可以实现比较精 ...

  10. 题解 e

    传送门 第一眼看貌似可以树剖,然而那个绝对值不知怎么维护 求最小连通块我只会\(k^2\) 主席树貌似可以用来查询区间内与某个数差的绝对值的最小值? 确实,每次查大于等于该数的最小数和小于等于该数的最 ...