Spring Boot2.0 @ConfigurationProperties使用详解
作者:paderlol 发布时间:2021-06-11 17:21:30
引言
Spring Boot的一个便捷功能是外部化配置,可以轻松访问属性文件中定义的属性。本文将详细介绍@ConfigurationProperties的使用。
配置项目POM
在pom.xml中定义Spring-Boot 为parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
添加依赖
添加web,因为我们需要使用到JSR-303规范的Validator,如果不想使用web依赖,也可以直接依赖hibernate-validator
添加spring-boot-configuration-processor,可以在编译时生成属性元数据(spring-configuration-metadata.json).
添加lombok,可以方便使用注释处理器的功能省去Pojo定义中get set这些麻烦工作.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.hibernate.validator</groupId>-->
<!--<artifactId>hibernate-validator</artifactId>-->
<!--<version>6.0.11.Final</version>-->
<!--<scope>compile</scope>-->
<!--</dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
例子编写
首先定义一个DocumentServerProperties对象,下面这个文档服务器配置是我假设的,主要是为了演示属性配置的大部分情况
@Getter
@Setter
public class DocumentServerProperties {
private String remoteAddress;
private boolean preferIpAddress;
private int maxConnections=0;
private int port;
private AuthInfo authInfo;
private List<String> whitelist;
private Map<String,String> converter;
private List<Person> defaultShareUsers;
@Getter
@Setter
public static class AuthInfo {
private String username;
private String password;
}
}
绑定属性配置
注意@ConfigurationProperties并没有把当前类注册成为一个Spring的Bean,下面介绍@ConfigurationProperties配置注入的三种方式.
配合@Component注解直接进行注入
@ConfigurationProperties(prefix = "doc")
@Component
public class DocumentServerProperties {
//代码...
}
使用@EnableConfigurationProperties,通常配置在标有@Configuration的类上,当然其他@Component注解的派生类也可以,不过不推荐.
@ConfigurationProperties(prefix = "doc")
public class DocumentServerProperties {
//代码...
}
@EnableConfigurationProperties
@Configuration
public class SomeConfiguration {
private DocumentServerProperties documentServerProperties
public SomeConfiguration(DocumentServerProperties documentServerProperties) {
this.documentServerProperties = documentServerProperties;
}
}
使用@Bean方式在标有@Configuration的类进行注入,这种方式通常可以用在对第三方类进行配置属性注册
@Configuration
public class SomeConfiguration {
@Bean
public DocumentServerProperties documentServerProperties(){
return new DocumentServerProperties();
}
@ConfigurationProperties("demo.third")
@Bean
public ThirdComponent thirdComponent(){
return new ThirdComponent();
}
}
编写配置文件
Spring-Boot中配置文件的格式有properties和yaml两种格式,针对上面的配置对象分别写了两种格式的配置文件例子.
Properties
doc.remote-address=127.0.0.1
doc.port=8080
doc.max-connections=30
doc.prefer-ip-address=true
#doc.whitelist=192.168.0.1,192.168.0.2
# 这种等同于下面的doc.whitelist[0] doc.whitelist[1]
doc.whitelist[0]=192.168.0.1
doc.whitelist[1]=192.168.0.2
doc.default-share-users[0].name=jack
doc.default-share-users[0].age=18
doc.converter.a=xxConverter
doc.converter.b=xxConverter
doc.auth-info.username=user
doc.auth-info.password=password
Yaml
doc:
remote-address: 127.0.0.1
port: 8080
max-connections: 30
prefer-ip-address: true
whitelist:
- 192.168.0.1
- 192.168.0.2
default-share-users:
- name: jack
age: 18
converter:
a: aConverter
b: bConverter
auth-info:
username: user
password: password
在上面的两个配置文件中,其实已经把我们平常大部分能使用到的属性配置场景都覆盖了,可能还有一些特殊的未介绍到,比如Duration、InetAddress等。
增加属性验证
下面我们利用JSR303规范的实现对DocumentServerProperties属性配置类,添加一些常规验证,比如Null检查、数字校验等操作,
需要注意在Spring-Boot 2.0版本以后,如果使用JSR303对属性配置进行验证必须添加@Validated注解,使用方式如下片段:
@ConfigurationProperties(prefix = "doc")
@Validated
public class DocumentServerProperties {
@NotNull // 判断不为空的情况
private String remoteAddress;
//限制端口只能是80-65536之间
@Min(80)
@Max(65536)
private int port;
//其他代码
}
在有些数情况下,我们希望自定义验证器,有两种方式可以进行实现
实现org.springframework.validation.Validator接口,并且在配置一个Bean名称必须叫configurationPropertiesValidator,代码如下:
public class UserLoginValidator implements Validator {
private static final int MINIMUM_PASSWORD_LENGTH = 6;
public boolean supports(Class clazz) {
return UserLogin.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "field.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
UserLogin login = (UserLogin) target;
if (login.getPassword() != null
&& login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
errors.rejectValue("password", "field.min.length",
new Object[]{Integer.valueOf(MINIMUM_PASSWORD_LENGTH)},
"The password must be at least [" + MINIMUM_PASSWORD_LENGTH + "] characters in );
}
}
}
和上面一样也是实现org.springframework.validation.Validator接口,不过是需要验证的属性配置类本身去实现这个接口
@ConfigurationProperties(prefix = "doc")
public class DocumentServerProperties implements Validator{
@NotNull
private String remoteAddress;
private boolean preferIpAddress;
//其他属性
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public void validate(Object target, Errors errors) {
//判断逻辑其实可以参照上面的代码片段
}
}
特别注意:
只有在需要使用JSR303规范实现的验证器时,才需要对对象配置@Validated,刚刚上面两种方式并不需要。
第一种实现和第二种实现都是实现org.springframework.validation.Validator接口,但是前者是针对全局的,后者只针对实现这个接口的配置对象
关于上述两点,我为啥确定? 来自ConfigurationPropertiesBinder的源码片段
private List<Validator> getValidators(Bindable<?> target) {
List<Validator> validators = new ArrayList<>(3);
if (this.configurationPropertiesValidator != null) {
validators.add(this.configurationPropertiesValidator);
}
if (this.jsr303Present && target.getAnnotation(Validated.class) != null) {
validators.add(getJsr303Validator());
}
if (target.getValue() != null && target.getValue().get() instanceof Validator) {
validators.add((Validator) target.getValue().get());
}
return validators;
}
总结
通过上面的例子,我们了解了@ConfigurationProperties的使用以及如何进行验证,包括属性验证器的几种实现方式.下个章节我会从源码的角度分析属性的加载,以及如何解析到Bean里面去的。
来源:https://segmentfault.com/a/1190000016941757


猜你喜欢
- 〇、正则表达式的基本语法符号若只简单匹配固定字符串,则无需任何修饰符,例如:需要匹配字符串 77,则可直接写:new Regex(
- 一. switch分支结构1. 简介switch结合case,能够判断一个变量或表达式与一系列值中的某个值是否相等,这里的每个值都被称为一个
- 基础知识介绍: @RequestBody主要用来接收前端传递给后端的json字符串中的
- 主要介绍了Java获取随机数的3种方法,主要利用random()函数来实现方法1(数据类型)(最小值+Math.random()*(最大值-
- 自定义 webflux 容器配置配置代码@Componentpublic class ContainerConfig extends Rea
- 1、右值1.1 简介首先区分一下左右值:左值是指存储在内存中、有明确存储地址(可取地址)的数据;右值是指可以提供数据值的数据(不可取地址)如
- 本文实例讲述了java识别一篇文章中某单词出现个数的方法。分享给大家供大家参考。具体如下:1. java代码:import java.io.
- Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持。Acegi是基于Spring IOC 和 AO
- 1、介绍官网地址:https://www.yuque.com/easyexcel特点:1、Java领域解析、生成Excel比较有名的框架有A
- 本文实例讲述了C#实现为一张大尺寸图片创建缩略图的方法。分享给大家供大家参考。具体实现方法如下:public static Bitmap C
- 对一个对象进行属性分析,并得到相应的属性值,并判断属性的默认值以及空值 public class People
- 这几天在做公司年会的一个抽奖软件,开始做的的时候,认为算法是很简单的,把员工的数据放进list里,把list的标号作为需要获取的随机数,根据
- Elastic Search是一个开源的,分布式,实时搜索和分析引擎。Spring Boot为Elasticsearch及Spring Da
- private void btnSetOk_Click(object sender, EventArgs e) &nb
- 本文实例主要实现了网页照相机程序的功能。C#实现将网页保存成图片格式,简单实现网页拍照,主要是基于ActiveX 组件的网页快照类,Acit
- 安装配置完Java的jdk,下面就开始写第一个java程序--hello World.用来在控制台输出“Hello World”。首先,我们
- 此文主要想和大家分享的是这段时间,对权限管理和设计的断断续续的思考学习,和个人的一些软件开发等方面的看法。 提到'权限管理和设计
- 概述本文的目的是实现以下的流程:Android/iOS native app 操作摄像头 -> 获取视频流数据 -> 人脸检测或
- Quartz是一款开源的定时任务调度框架,Quartz的官网是:http://www.quartz-s
- 题外话:发现好久都没有上来写博文了,毕业设计加上公司暂时没有Android的项目做,只能去自学web上的知识,摸爬打滚到现在,花了一个多月时