Spring Boot(07)——ConfigurationProperties介绍

简介:

ConfigurationProperties介绍

ConfigurationProperties是一个注解,可以标注在一个Class上,这样Spring Boot会从Environment中获取其属性对应的属性值给其进行注入。比如下面的代码定义中,Spring Boot在实例化TestConfigurationProperties这个bean时就会把从Environment中获取属性名为appName的属性值赋给TestConfigurationProperties的appName属性。

@ConfigurationProperties
@Data
public class TestConfigurationProperties {

    private String appName;
    
}

所以当你的application.properties文件中定义了appName=Test时就会把Test赋值给TestConfigurationProperties对象的appName属性。实际上下面的定义和appName=Test是等价的。也就是说在从Environment中获取属性值绑定到ConfigurationProperties标注的对象上时,对大小写是不敏感的,而且其中的-_都会被剔除。

APPname=Test
app-Name=Test
app-name=Test
app_name=Test

@ConfigurationProperties标注的Class通常用于从Environment中绑定属性值,然后供bean容器中的其它bean使用,通常是跟@Configuration标注的Class一起使用,其内部会注入@ConfigurationProperties标注的对象用来定义bean。如果你去查看Spring Boot的AutoConfiguration包,你会发现里面基本都是这样的用法。单独跟@Configuration标注的Class一起使用时,通常还会在@Configuration标注的Class上加上@EnableConfigurationProperties指定允许使用的标注了@ConfigurationProperties的配置类,这样Spring Boot就会把它实例化为一个bean,然后在@Configuration配置类中就可以进行依赖注入并进行使用了。以下代码就是一个简单的示例。

@Configuration
@EnableConfigurationProperties(TestConfigurationProperties.class)
public class TestConfig {

    @Autowired
    private TestConfigurationProperties props;
    
    @Bean
    public Object initBean() {
        //使用注入的ConfigurationProperties标注的对象进行bean构造
        return this.props.getAppName();
    }
    
}

@ConfigurationProperties标注的Class本身就标注为一个bean定义时就不需要在@Configuration标注的Class上使用@EnableConfigurationProperties进行指定了,可以直接进行注入,因为它已经是一个bean了。

指定需要映射的前缀

在application.properties文件中定义的属性通常不是单一名称的属性,而是以a.b.c.d这种形式构成的属性,多个层级之间以点分隔,从而形成不同的分类。这种属性需要绑定到@ConfigurationProperties标注的对象属性上时可以指定一个通用的前缀,然后只对去除前缀之后的内容进行绑定。下面的代码指定了绑定属性时的前缀是test.config,所以TestConfigurationProperties对象的username属性将绑定配置文件中的test.config.username属性,password属性将匹配配置文件中的test.config.password属性。

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private String username;
    
    private String password;
    
}

当在application.properties文件中进行了如下定义时,TestConfigurationProperties对象的username属性绑定的值是u1,password属性绑定的值是p1

test.config.username=u1
test.config.password=p1

@ConfigurationProperties中有一个属性value用来指定前缀,属性prefix也可以用来指定前缀。有一个ignoreInvalidFields用来指定当需要绑定的属性值不合法时是否需要忽略该属性绑定,属性不合法主要是指类型不匹配。比如需要绑定值的属性定义的类型是int,通过自动绑定机制获取到的属性值是abc,它就不能转换为int。ignoreInvalidFields默认是false,即当出现属性不合法时将不忽略,将抛出异常。还有一个ignoreUnknownFields属性,用来指定当需要绑定值的属性没有找到对应的绑定属性时是否将忽略,默认是true

级联绑定

下面的代码中TestConfigurationProperties的inner属性是一个对象,需要对其进行绑定时需要以.进行级联绑定。

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private Inner inner;
    
    @Data
    public static class Inner {
        private String username;
        private String password;
    }
    
}

在application.properties文件中进行如下定义会为TestConfigurationProperties对象的inner属性绑定一个Inner对象,其username属性的值是u1,password的值是p1。

test.config.inner.username=u1
test.config.inner.password=p1

在application.yml文件中进行如下定义与上面的定义等价。

test.config.inner:
  username: u1
  password: p1

绑定集合属性

下面的代码中使用@ConfigurationProperties标注的Class有一个List类型的属性。

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private List<String> list;
    
}

需要给List绑定值时,可以通过[index]的形式指定值,下面的代码就定义了List中的三个元素,分别是ABCDEFGHI

test.config.list[0]=ABC
test.config.list[1]=DEF
test.config.list[2]=GHI

也可以使用英文逗号分隔List中的多个值,以下配置跟上面的配置是等价的。

test.config.list=ABC,DEF,GHI

Set、Array类型的属性值绑定也可以使用类似的语法(索引和逗号分隔)。

在YAML配置文件定义集合类型的值绑定时可以定义为如下这样:

test.config.list:
  - ABC
  - DEF
  - GHI

它也可以使用逗号分隔的多个值。

test.config.list: ABC,DEF,GHI

如果需要绑定值的集合元素是一个对象怎么办呢?下面的代码中list属性的元素类型就是一个Inner对象,其中Inner对象又有username和password两个属性。

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private List<Inner> list;
    
    @Data
    public static class Inner {
        private String username;
        private String password;
    }
    
}

在application.properties文件中进行如下定义可以为list属性绑定两个Inner对象,其中第一个对象的username属性值为u1,password属性值为p1;第二个对象的username属性值为u2,password属性值为p2。

test.config.list[0].username=u1
test.config.list[0].password=p1

test.config.list[1].username=u2
test.config.list[1].password=p2

在application.yml文件中进行如下定义与上面的定义等价,可以达到相同的值绑定效果。

test.config.list:
  -
    username: u1
    password: p1
  -
    username: u2
    password: p2

绑定Map属性

下面的代码中拥有一个Map类型的map属性,Key和Value都是String类型。

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private Map<String, String> map;
    
}

需要给上面的map属性绑定值时可以使用key=value的形式,下面的配置会给map属性绑定两个元素,分别是key1对应value1,key2对应value2。

test.config.map.key1=value1
test.config.map.key2=value2

在application.yml文件中使用YAML语法定义就更简单了,以下定义等价于上面的定义。

test.config.map:
  key1: value1
  key2: value2

如果需要绑定的Value是一个对象怎么办呢?比如map属性的定义改为如下这样:

@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    private Map<String, Inner> map;
    
    @Data
    public static class Inner {
        private String username;
        private String password;
    }
    
}

在application.properties文件中进行如下定义,会绑定两个元素到map,第一个元素的Key是key1,Value是一个Inner对象,其username属性的值是u1,password属性的值是p1;第二个元素的Key是key2,Value的username属性的值是u2,password属性的值是p2。

test.config.map.key1.username=u1
test.config.map.key1.password=p1

test.config.map.key2.username=u2
test.config.map.key2.password=p2

在application.yml文件中定义时,如下定义等价于上面的定义。

test.config.map:
  key1:
    username: u1
    password: p1
  key2:
    username: u2
    password: p2

使用JSR303注解进行有效性校验

可以对@ConfigurationProperties标注的Class的属性进行有效性校验,要使校验生效,需要在Class上添加@org.springframework.validation.annotation.Validated,还需要Classpath下拥有JSR303 Validator的实现,比如Hibernate Validator,这样Spring Boot在进行属性值绑定后会校验其合法性。下面的代码中就指定了name属性不能为null或空字符串,如果绑定后的值为空将抛出异常。

@Validated
@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    @NotBlank(message="参数test.config.name不能为空")
    private String name;
    
}

如果需要进行属性值绑定的属性是一个对象,需要对该对象中的某个属性进行合法性校验,比如下面代码中需要对Inner对象中的username属性进行非空校验,则需要在inner属性上加上@Valid,同时在username属性上加上@NotBlank

@Validated
@ConfigurationProperties("test.config")
@Data
public class TestConfigurationProperties {

    @NotBlank(message="参数test.config.name不能为空")
    private String name;
    
    @Valid
    private Inner inner;
    
    @Data
    public static class Inner {
        
        @NotBlank(message="参数test.config.inner.username不能为空")
        private String username;
        private String password;
    }
    
}

绑定属性值到第三方jar中包含的Class

如果需要绑定属性值到第三方jar中包含的Class对象,我们是无法直接在Class上加上@ConfigurationProperties注解的,这时候可以在@Configuration标注的Class中定义一个需要绑定值的Class类型的bean,然后在该方法上加上@ConfigurationProperties。比如下面代码中通过initTestConfigurationProperties()定义了一个TestConfigurationProperties类型的bean,在该方法上加上了@ConfigurationProperties,Spring Boot就会为该bean进行属性值绑定。

@Configuration
public class TestConfig {

    @Bean
    @ConfigurationProperties("test.config")
    public TestConfigurationProperties initTestConfigurationProperties() {
        return new TestConfigurationProperties();
    }
    
}

参考文档

https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties

(注:本文是基于Spring Boot 2.0.3所写)

目录
相关文章
|
22天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
15 0
|
XML Java 数据格式
SpringBoot入门(五) 之 @ConfigurationProperties和@Value的区分与用法
SpringBoot入门(五) 之 @ConfigurationProperties和@Value的区分与用法
160 0
|
前端开发 Java Nacos
《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?
《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?
719 1
《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?
|
Java 开发者 Spring
《SpringBoot篇》07.@ConfigurationProperties注解实现第三方bean加载属性
《SpringBoot篇》07.@ConfigurationProperties注解实现第三方bean加载属性
248 0
《SpringBoot篇》07.@ConfigurationProperties注解实现第三方bean加载属性
|
Java Spring 容器
第九篇:SpringBoot 配置高级 ConfigurationProperties注解 宽松绑定/松散绑定
第九篇:SpringBoot 配置高级 ConfigurationProperties注解 宽松绑定/松散绑定
302 0
第九篇:SpringBoot 配置高级 ConfigurationProperties注解 宽松绑定/松散绑定
|
JSON Java Maven
【SpringBoot基础系列】ConfigurationProperties 配置绑定中那些你不知道的事情
在 SpringBoot 项目中,获取配置属性可以说是一个非常简单的事情,将配置写在aplication.yml文件之后,我们就可以直接通过@Value注解来绑定并获取;此外我们也可以将一个结构化的配置,借助@ConfigurationPorperties绑定到一个 POJO,然后供项目使用,那么在使用它的时候,不知是否有想过
473 0
【SpringBoot基础系列】ConfigurationProperties 配置绑定中那些你不知道的事情
|
Java 容器
SpringBoot中配置绑定的三种方法(@ConfigurationProperties注解)
SpringBoot中配置绑定的三种方法(@ConfigurationProperties注解)
337 0
SpringBoot中配置绑定的三种方法(@ConfigurationProperties注解)
SpringBoot中使用@ConfigurationProperties
SpringBoot中使用@ConfigurationProperties
|
Java 数据库
SpringBoot | @Value 和 @ConfigurationProperties 的区别
最近有跳槽的想法,所以故意复习了下 SpringBoot 的相关知识,复习得比较细。其中有些,我感觉是以前忽略掉的东西,比如 @Value 和 @ConfigurationProperties 的区别 。
|
Java Spring
SpringBoot中@ConfigurationProperties提示:Configuration Annotation Processor not found in classpath
SpringBoot中@ConfigurationProperties提示:Configuration Annotation Processor not found in classpath
398 0