Spring Boot2.0 @ConfigurationProperties使用详解

 更新时间:2018年11月08日 11:20:09   作者:paderlol  
这篇文章主要介绍了Spring Boot2.0 @ConfigurationProperties使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

引言

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>

添加依赖

  1. 添加web,因为我们需要使用到JSR-303规范的Validator,如果不想使用web依赖,也可以直接依赖hibernate-validator
  2. 添加spring-boot-configuration-processor,可以在编译时生成属性元数据(spring-configuration-metadata.json).
  3. 添加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里面去的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Spring常见的事务失效场景及解决方案

    Spring常见的事务失效场景及解决方案

    Spring 事务管理是企业级应用开发中不可或缺的一部分,它可以帮助我们确保数据的一致性和完整性,然而,在实际开发中,由于各种原因,事务可能会失效,本文将详细介绍 Spring 事务失效的常见情况,并提供相应的解决方案和示例代码,需要的朋友可以参考下
    2024-11-11
  • Java求解二叉树的最近公共祖先实例代码

    Java求解二叉树的最近公共祖先实例代码

    树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合,这篇文章主要给大家介绍了关于Java求解二叉树的最近公共祖先的相关资料,需要的朋友可以参考下
    2021-06-06
  • Mybatis Properties 配置优先级详解

    Mybatis Properties 配置优先级详解

    这篇文章主要介绍了Mybatis Properties 配置优先级,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringCloud中的灰度路由使用详解

    SpringCloud中的灰度路由使用详解

    这篇文章主要介绍了SpringCloud中的灰度路由使用详解,在微服务中, 通常为了高可用, 同一个服务往往采用集群方式部署, 即同时存在几个相同的服务,而灰度的核心就 是路由, 通过我们特定的策略去调用目标服务线路,需要的朋友可以参考下
    2023-08-08
  • Java List集合去重的多种实现方法

    Java List集合去重的多种实现方法

    Java中List集合去重的多种方法,包括使用循环、HashSet、保持顺序去重、contain方法去重等,注意在删除元素时,直接操作会导致ConcurrentModificationException,应使用传统for循环或倒序删除
    2025-02-02
  • Java编码算法与哈希算法深入分析使用方法

    Java编码算法与哈希算法深入分析使用方法

    首先,我们一起来学习一下编码算法,举例说明,ASCII码就是我们常见的一种编码,字母a的编码是十六进制的0x61,字母b是0x62,以此类推。哈希算法,可被称为摘要算法。因此,哈希算法的加密是单向的,不可用密文解密得到明文
    2022-11-11
  • MyBatis中动态sql的实现方法示例

    MyBatis中动态sql的实现方法示例

    这篇文章主要给大家介绍了关于MyBatis中动态sql的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 用Java实现一个简单的布隆过滤器

    用Java实现一个简单的布隆过滤器

    这篇文章主要介绍了用Java实现一个简单的布隆过滤器,布隆过滤器是1970年由布隆提出的,它实际上是一个很长的二进制向量和一系列随机映射函数,布隆过滤器可以用于检索一个元素是否在一个集合中,需要的朋友可以参考下
    2023-12-12
  • 浅谈在页面中获取到ModelAndView绑定的值方法

    浅谈在页面中获取到ModelAndView绑定的值方法

    下面小编就为大家分享一篇浅谈在页面中获取到ModelAndView绑定的值方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • springboot整合flowable框架入门步骤

    springboot整合flowable框架入门步骤

    最近工作中有用到工作流的开发,引入了flowable工作流框架,在此记录一下springboot整合flowable工作流框架的过程,感兴趣的朋友一起看看吧
    2022-04-04

最新评论