IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot自定义配置时@Value和@ConfigurationProperties孰优孰劣? -> 正文阅读

[Java知识库]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;
    }
}

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

PropertyNote
my.main-project.person.first-nameKebab 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)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 12:48:23  更:2022-03-06 12:50:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:24:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码