利用 Spring Boot 中的 @ConfigurationProperties,优雅绑定配置参数
使用 @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 中引入的。

参考
- @ConfigurationProperties 注解使用姿势,这一篇就够了
- @ConfigurationProperties注解与@Value注解区别
- Spring Boot 官网 -- 版本 2.5.4
- Spring-boot-configration-processor 的作用
利用 Spring Boot 中的 @ConfigurationProperties,优雅绑定配置参数的更多相关文章
- Spring Boot中注解@ConfigurationProperties
在Spring Boot中注解@ConfigurationProperties有三种使用场景,而通常情况下我们使用的最多的只是其中的一种场景.本篇文章带大家了解一下三种场景的使用情况. 场景一 使用@ ...
- Spring Boot中只能有一个WebMvcConfigurationSupport配置类
首先将结论写文章的最前面,一个项目中只能有一个继承WebMvcConfigurationSupport的@Configuration类(使用@EnableMvc效果相同),如果存在多个这样的类,只有一 ...
- 在Spring Boot中使用 @ConfigurationProperties 注解
但 Spring Boot 提供了另一种方式 ,能够根据类型校验和管理application中的bean. 这里会介绍如何使用@ConfigurationProperties.继续使用mail做例子. ...
- 在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties
但 Spring Boot 提供了另一种方式 ,能够根据类型校验和管理application中的bean. 这里会介绍如何使用@ConfigurationProperties.继续使用mail做例子. ...
- Spring Boot 中 Druid 的监控页面配置
Druid的性能相比HikariCp等其他数据库连接池有一定的差距,但是数据库的相关属性的监控,别的连接池可能还追不上,如图: 今天写一下 Spring Boot 中监控页面的配置,我是直接将seat ...
- 曹工谈Spring Boot:Spring boot中怎么进行外部化配置,一不留神摔一跤;一路debug,原来是我太年轻了
spring boot中怎么进行外部化配置,一不留神摔一跤:一路debug,原来是我太年轻了 背景 我们公司这边,目前都是spring boot项目,没有引入spring cloud config,也 ...
- Spring Boot 中使用 @ConfigurationProperties 注解
@ConfigurationProperties 主要作用:绑定 application.properties 中的属性 例如: @Configuration public class DataSou ...
- 在Spring Boot中使用 @ConfigurationProperties 注解 (二十六)
@ConfigurationProperties主要作用:就是绑定application.properties中的属性 java代码 @Configuration public class DataS ...
- 在Spring Boot中使用数据缓存
春节就要到了,在回家之前要赶快把今年欠下的技术债还清.so,今天继续.Spring Boot前面已经预热了n篇博客了,今天我们来继续看如何在Spring Boot中解决数据缓存问题.本篇博客是以初识在 ...
随机推荐
- 关于intouch/ifix嵌入视频控件并使用(海康,大华)
2017年下半年项目开始接触利用intouch工控软件来进行项目二次开发.其中关于驱动的问题始终是上位机的重中之重,暂且不表(嘿嘿--),首先遇到的问题就是在弹窗中嵌入视频控件,监控设备的开停状态.经 ...
- xss.haozi靶机
X00 <script>alert(1)</script> X01 </textarea><script>alert(1)</script> ...
- 自学 linux——14.mysql的基本操作
MySQL的基本操作 1.名词介绍 以Excel文件举例: 数据库:可以看作是整个excel文件. 数据表:可以看作是一个excel文件中的工作表. 行(记录):可以看作是一个工作表中的一行 列(字段 ...
- MySQL 索引使用案例
索引使用案例 支持多种过滤条件 假设要设计一个在线约会网站,用户信息表有很多列,包括国家.地区.城市.性别.眼睛颜色,等等.网站必须支持上面这些特征的各种组合来搜索用户,还必须允许根据用户的最后在线时 ...
- 流量加密-Kali使用Openssl反弹shell
Kali使用Openssl反弹shell 前言 之前在护网的时候,如果流量中有明文的敏感信息,譬如攻击特征,是很容易被IDS检测出来的,此时红队的攻击行为就会暴露.这是非常危险的一件事.今天我们通过本 ...
- 面试利器!字节跳动2021年Android程序员面试指导小册已开源
整份手册分为两个部分,分别是:Java部分.Android部分.数据结构与算法篇.字节跳动2020年全年面试题总结篇! 每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多,这里就截取一部分图 ...
- 超详细Java基础-多态
茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...
- JAVA基础语法:函数(方法)、类和对象(转载)
4.JAVA基础语法:函数(方法).类和对象 函数 在java中函数也称为方法,是一段具备某种功能的可重用代码块. 一个函数包括这几部分: 函数头 函数头包括函数访问修饰符,函数返回值类型, 函数名, ...
- 快速理解VLAN与三层交换机
一.VLAN 1.1.VLAN的概述与优势 VLAN是逻辑隔离的虚拟局域网,作用是分割广播域(分为物理分割和逻辑分割) VLAN的优势:控制广播.增强网络安全性.简化网络管理 1.2.VLAN的种类 ...
- Git-05-文件删除与恢复
删除文件 1 添加一个文件test.txt文件用于测试 2 删除文件,这样删除,工作区和版本库一致 也可以直接rm 然后在 git rm,git commit 这样也能保证工作区和版本库一致 恢复误删 ...