Spring Boot2.0 @ConfigurationProperties使用详解
引言
SpringBoot的一个便捷功能是外部化配置,可以轻松访问属性文件中定义的属性。本文将详细介绍@ConfigurationProperties的使用。
配置项目POM
在pom.xml中定义Spring-Boot为parent
org.springframework.boot spring-boot-starter-parent 2.0.4.RELEASE
添加依赖
- 添加web,因为我们需要使用到JSR-303规范的Validator,如果不想使用web依赖,也可以直接依赖hibernate-validator
- 添加spring-boot-configuration-processor,可以在编译时生成属性元数据(spring-configuration-metadata.json).
- 添加lombok,可以方便使用注释处理器的功能省去Pojo定义中getset这些麻烦工作.
org.springframework.boot spring-boot-starter-web org.projectlombok lombok org.springframework.boot spring-boot-configuration-processor true
例子编写
首先定义一个DocumentServerProperties对象,下面这个文档服务器配置是我假设的,主要是为了演示属性配置的大部分情况
@Getter @Setter publicclassDocumentServerProperties{ privateStringremoteAddress; privatebooleanpreferIpAddress; privateintmaxConnections=0; privateintport; privateAuthInfoauthInfo; privateListwhitelist; privateMap converter; privateList defaultShareUsers; @Getter @Setter publicstaticclassAuthInfo{ privateStringusername; privateStringpassword; } }
绑定属性配置
注意@ConfigurationProperties并没有把当前类注册成为一个Spring的Bean,下面介绍@ConfigurationProperties配置注入的三种方式.
配合@Component注解直接进行注入
@ConfigurationProperties(prefix="doc") @Component publicclassDocumentServerProperties{ //代码... }
使用@EnableConfigurationProperties,通常配置在标有@Configuration的类上,当然其他@Component注解的派生类也可以,不过不推荐.
@ConfigurationProperties(prefix="doc") publicclassDocumentServerProperties{ //代码... }
@EnableConfigurationProperties @Configuration publicclassSomeConfiguration{ privateDocumentServerPropertiesdocumentServerProperties publicSomeConfiguration(DocumentServerPropertiesdocumentServerProperties){ this.documentServerProperties=documentServerProperties; } }
使用@Bean方式在标有@Configuration的类进行注入,这种方式通常可以用在对第三方类进行配置属性注册
@Configuration publicclassSomeConfiguration{ @Bean publicDocumentServerPropertiesdocumentServerProperties(){ returnnewDocumentServerProperties(); } @ConfigurationProperties("demo.third") @Bean publicThirdComponentthirdComponent(){ returnnewThirdComponent(); } }
编写配置文件
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-Boot2.0版本以后,如果使用JSR303对属性配置进行验证必须添加@Validated注解,使用方式如下片段:
@ConfigurationProperties(prefix="doc") @Validated publicclassDocumentServerProperties{ @NotNull//判断不为空的情况 privateStringremoteAddress; //限制端口只能是80-65536之间 @Min(80) @Max(65536) privateintport; //其他代码 }
在有些数情况下,我们希望自定义验证器,有两种方式可以进行实现
实现org.springframework.validation.Validator接口,并且在配置一个Bean名称必须叫configurationPropertiesValidator,代码如下:
publicclassUserLoginValidatorimplementsValidator{ privatestaticfinalintMINIMUM_PASSWORD_LENGTH=6; publicbooleansupports(Classclazz){ returnUserLogin.class.isAssignableFrom(clazz); } publicvoidvalidate(Objecttarget,Errorserrors){ ValidationUtils.rejectIfEmptyOrWhitespace(errors,"userName","field.required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors,"password","field.required"); UserLoginlogin=(UserLogin)target; if(login.getPassword()!=null &&login.getPassword().trim().length()和上面一样也是实现org.springframework.validation.Validator接口,不过是需要验证的属性配置类本身去实现这个接口
@ConfigurationProperties(prefix="doc") publicclassDocumentServerPropertiesimplementsValidator{ @NotNull privateStringremoteAddress; privatebooleanpreferIpAddress; //其他属性 @Override publicbooleansupports(Class>clazz){ returntrue; } @Override publicvoidvalidate(Objecttarget,Errorserrors){ //判断逻辑其实可以参照上面的代码片段 } }特别注意:
- 只有在需要使用JSR303规范实现的验证器时,才需要对对象配置@Validated,刚刚上面两种方式并不需要。
- 第一种实现和第二种实现都是实现org.springframework.validation.Validator接口,但是前者是针对全局的,后者只针对实现这个接口的配置对象
关于上述两点,我为啥确定?来自ConfigurationPropertiesBinder的源码片段
privateListgetValidators(Bindable>target){ List validators=newArrayList<>(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()instanceofValidator){ validators.add((Validator)target.getValue().get()); } returnvalidators; } 总结
通过上面的例子,我们了解了@ConfigurationProperties的使用以及如何进行验证,包括属性验证器的几种实现方式.下个章节我会从源码的角度分析属性的加载,以及如何解析到Bean里面去的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。