《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?

简介: 《SpringBoot系列三》:自定义配置时@Value和@ConfigurationProperties孰优孰劣?

一、@Value

通过@Value我们可以直接将属性值注入到IOC容器的相应bean 中,业务上我们注入单个属性时最常使用的也是这种方式。

不过,有时使用@Value("${property}")注解来注入配置属性有时会很麻烦,尤其是当要使用多个属性 或 数据本质上是分层的 时。

所以,Spring Boot 提供了一种使用属性的替代方法,可以让强类型 bean 管理和验证应用程序的配置。

使用方式:

需要使用到属性的JavaBean中:

@Value("${test.test}")
private String test;

yaml文件:

test:
  test: test-resources/

二、@ConfigurationProperties

@ConfigurationProperties加载配置是通过BeanPostProcessor实现,其对应的Bean的后置处理器为ConfigurationPropertiesBindingPostProcessor。也就是说在bean被实例化后,会调用后置处理器,递归的查找属性,通过反射机制注入值,因此属性需要提供setter和getter方法。
此外,针对此种属性注入的方式,SpringBoot支持Relaxed Binding,即只需保证配置文件的属性和setter方法名相同即可。

在这里插入图片描述
在SpringBoot官方文档中有几个注意点:

  • 属性必须要有getter、setter方法;
  • 如果属性的类型是集合,要确保集合是不可变的;
  • 如果使用Lombok自动生成getter/setter方法,一定不要生成对应的任何构造函数,因为Spring IOC容器会自动使用它来实例化对象。
  • 使用JavaBean属性绑定的方式只针对标准 Java Bean 属性,不支持对静态属性的绑定。

当我们使用@ConfigurationProperties注解进行属性注入时,记得在pom.xml文件中添加spring-boot-configuration-processor依赖,

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

否则相应类上会有一行红色的异常信息,具体如下:

Spring Boot Configuration Annotation Processor not found in classpath

并且在pom中加上spring-boot-configuration-processor依赖之后,我们使用@ConfigurationProperties注解注释的配置类中的字段,在yaml文件中会自动带出提示 / 补全。
在这里插入图片描述

1、@EnableConfigurationProperties

Spring考虑到带有注释@ConfigurationProperties的类可能不适合扫描(比如:我正在开发自己的自动配置或希望有条件地启用它们),所以Spring并不会自动扫描带有注释@ConfigurationProperties的类。

在这些情况下,推荐使用@EnableConfigurationProperties注解指定要处理的类型列表(即:将@ConfigurationProperties注释的类加到Spring IOC容器中)。一般通过将@EnableConfigurationProperties加在@Configuration类上完成。

使用方式1:@EnableConfigurationProperties + @Configuration + @ConfigurationProperties

如下例所示:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SomeProperties.class)
public class MyConfiguration {

}
@ConfigurationProperties(prefix = "some.properties")
public class SomeProperties {
    private String test;
}

这种方式在Spring源码中被广泛使用:

比如:Spring MVC的配置类(WebMvcProperties)
在这里插入图片描述
其在WebMvcAutoConfiguration类的静态内部类WebMvcAutoConfigurationAdapter上被通过@Configuration + @EnableConfigurationProperties的方式被注入到Spring IOC容器中。
在这里插入图片描述

使用方式2:@Configuration + @ConfigurationProperties

直接将@Configuration注解 和 @ConfigurationProperties注解加在JavaBean上,让Spring IOC可以自动扫描到 @ConfigurationProperties注解标注的类。

@Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = "some.properties")
public class SomeProperties {
    private String test;
}

2、宽松绑定(Relaxed Binding)

Spring Boot 中使用一些宽松的规则将环境属性(可以理解为配置文件application.yml中的属性)绑定到bean中,也就是说:yaml文件中的属性名称和 JavaBean属性名称@ConfigurationProperties之间不需要完全匹配。包括:

  • 破折号分隔的环境属性(context-path绑定到contextPath)
  • 大写环境属性(PORT绑定到port)

例如,考虑以下@ConfigurationProperties类:

@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;
    }
}

使用上述代码时,可以使用以下属性名称:

Property Note
my.main-project.person.first-name Kebab case,通常使用在 .properties.yml 文件中
my.main-project.person.firstName 标准驼峰方式
my.main-project.person.first_name 下划线表示法,在.properties.yml文件中使用的另一种格式
MY_MAINPROJECT_PERSON_FIRSTNAME 大写格式,在使用系统环境变量时推荐使用

注意:@ConfigurationProperties注解中prefix的值必须是 kebab 大小写(小写并用 分隔-,例如my.main-project.person)

每种属性源的宽松绑定规则

在这里插入图片描述

3、JSR-303对@ConfigurationProperties验证

每当使用 Spring 的注解@Validated进行注解时,Spring Boot 都会尝试验证类。我们可以直接在配置类上使用 JSR-303约束注释。

@ConfigurationProperties("my.service")
@Validated
public class MyProperties {

    @NotNull
    private InetAddress remoteAddress;

    // getters/setters...

}

注:注释@Bean创建配置属性的方法来也可以触发验证@Validated

4、第三方配置

@ConfigurationProperties除了用于注释类之外,还可以在公共@Bean方法上使用它。当想要将属性绑定到我们无法控制的第三方组件时,这样做会特别有用。

@Configuration(proxyBeanMethods = false)
public class ThirdPartyConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "another")
    public AnotherComponent anotherComponent() {
        return new AnotherComponent();
    }

}

三、@Value和@ConfigurationProperties的区别?

  • @ConfigurationProperties注解支持属性文件和javabean的映射;而@Value支持spel表达式。
  • @ConfigurationProperties注解支持全量的属性 宽松绑定方式;而@Value只推荐使用标准的kebab-case方式(仅使用小写字母和-),例如:@Value("{demo.item-price}")可以提取demo.item-pricedemo.itemPrice
  • 对于多个属性映射,并且属性常常被复用时,推荐使用@ConfigurationProperties;只读取单个属性使用@Value更简单方便。

四、SpringBoot配置加载优先级

移步至:SprintBoot:配置文件加载优先级(含服务注册中心nacos)

相关文章
|
4月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
78 4
|
3月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
79 0
|
1月前
|
JavaScript Java 程序员
SpringBoot自动配置及自定义Starter
Java程序员依赖Spring框架简化开发,但复杂的配置文件增加了负担。SpringBoot以“约定大于配置”理念简化了这一过程,通过引入各种Starter并加载默认配置,几乎做到开箱即用。
115 10
SpringBoot自动配置及自定义Starter
|
4月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
85 0
|
2月前
|
Java Maven Spring
SpringBoot配置跨模块扫描问题解决方案
在分布式项目中,使用Maven进行多模块开发时,某些模块(如xxx-common)没有启动类。如何将这些模块中的类注册为Spring管理的Bean对象?本文通过案例分析,介绍了两种解决方案:常规方案是通过`@SpringBootApplication(scanBasePackages)`指定扫描路径;推荐方案是保持各模块包结构一致(如com.xxx),利用SpringBoot默认扫描规则自动识别其他模块中的组件,简化配置。
SpringBoot配置跨模块扫描问题解决方案
|
2月前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
148 14
|
3月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
147 1
SpringBoot入门(7)- 配置热部署devtools工具
|
3月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
66 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
3月前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
77 3
|
3月前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
83 8