首页 > 其他分享 >@ConfigurationProperties VS @Value,你觉得哪个更好用

@ConfigurationProperties VS @Value,你觉得哪个更好用

时间:2024-09-09 14:23:09浏览次数:3  
标签:coder name sun Value note ConfigurationProperties VS



文章目录

  • 使用
  • 测试
  • @ConfigurationProperties和@Value区别
  • 复杂类型封装
  • 松散绑定
  • 元数据支持
  • SpEL表达式
  • JSR-303 数据校验
  • 总结



实际工作中,我们经常会看到或用到@ConfigurationProperties@Value 注解来注入自定义配置属性,那它们之间有什么不同呢?本文将从松散绑定 、参数校验、SpEL表达式、元数据支持等多方面介绍两者之间的不同之处。

使用

先看一下怎么使用它们。

  1. 先自定义几个配置属性
sun-coder-note.name=索码理
sun-coder-note.en_name=sunocdernote
# 粉丝数
sun-coder-note.fansCount=10000000
# 阅读数
sun-coder-note.read-count=10000000

sun-coder-note.article.title=自定义配置@ConfigurationProperties和@Value区别
sun-coder-note.article.category=springboot系列
  1. 使用 @ConfigurationProperties 注解接收自定义属性

定义一个SunCoderNoteProperties类, 使用 @ConfigurationProperties 注解接收自定义属性

@Data
@Configuration
@ConfigurationProperties(prefix = "sun-coder-note")
public class SunCoderNoteProperties {

    /**
     * 中文名
     */
    private String name;

    /**
     * 英文名
     */
    private String enName;

    /**
     * 粉丝数
     */
    private Integer fansCount;

    /**
     * 阅读数
     */
    private Integer readCount;

    /**
     * 文章
     */
    private ArticleProperties article;
}

通常情况下,在使用 @ConfigurationProperties 注解时,只要指定prefix前缀属性即可,同时 @Configuration 也要一起使用,要不然Springboot识别不到自定义的属性。

  1. 使用 @Value 注解获取自定义属性

在属性上使用 @Value 注解 ,使用 $ 符号直接获取自定义属性名对应的值。

@Data
@Configuration
public class SunCoderNoteValueProperties {

    @Value("${sun-coder-note.name}")
    private String name;

    @Value("${sun-coder-note.en-name}")
    private String enName;

    @Value("${sun-coder-note.fans-count}")
    private Integer fansCount;

    @Value("${sun-coder-note.read-count}")
    private Integer readCount;
}

测试

上面两个属性类定义好后,通过单元测试,测试能否获取到值。

@SpringBootTest
class PropertiesApplicationTests {

    @Resource
    private SunCoderNoteProperties sunCoderNoteProperties;
    @Resource
    private SunCoderNoteValueProperties sunCoderNoteValueProperties;

    @Test
    public void testBean(){
        System.out.println(sunCoderNoteProperties);
        System.out.println();
        System.out.println(sunCoderNoteValueProperties);
    }
}

通过测试,查看控制台,可以看到两种方式都能够获取到对应的属性值。

SunCoderNoteProperties(name=索码理, enName=sunocdernote, fansCount=10000000, readCount=10000000, article=ArticleProperties(title=自定义配置@ConfigurationProperties和@Value区别, category=springboot系列))

SunCoderNoteValueProperties(name=索码理, enName=sunocdernote, fansCount=10000000, readCount=10000000)

@ConfigurationProperties和@Value区别

既然 @ConfigurationProperties@Value 都能够获取到自定义属性的值,那么它们之间有什么区别呢? 不用我说,聪明的你通过上面的使用示例也能看出一些区别,下面我会总结一下它们的区别并逐个进行介绍。

特性

@ConfigurationProperties

@Value

复杂类型封装

支持

不支持

松散绑定

支持

支持(有限制)

SpEL表达式

不支持

支持

JSR-303 数据校验

支持

不支持

元数据支持

支持

不支持

复杂类型封装

  • @ConfigurationProperties: 支持复杂类型的封装,比如上面的 ArticleProperties ,除此之外还支持列表、集合等。
  • @Value: 通常只支持简单类型的封装,不适用于复杂类型的直接注入。

松散绑定

松散绑定是一种在属性绑定时提供灵活性的机制,它允许配置文件中的属性名与Java类中的字段名之间存在一定的差异,不需要严格匹配。

松散绑定支持多种不同的命名风格,包括驼峰式短横线隔开式下划线表示法 以及大写格式

  • 短横线隔开式:建议在.properties和 YAML配置文件中使用。
  • 下划线表示法:可以选择在.properties和 YAML配置文件中使用。
  • 大写格式:建议在使用系统环境变量时使用。

下面举例说明一下:

示例

以使用了 @ConfigurationProperties 注解的SunCoderNoteProperties类的enName属性为例。

  • 在配置文件中,可以使用以下任意一种形式来配置该属性:
  • sun-coder-note.enName=sunocdernote
  • sun-coder-note.en-name=sunocdernote
  • sun-coder-note.en_name=sunocdernote
  • sun-coder-note.EN_NAME=sunocdernote

SpringBoot的松散绑定机制都可以自动将这些配置映射到SunCoderNoteProperties类的enName属性上。

但对于 @Value注解来说,它是有一定的限制的,比如下面3种命名方式:

  • sun-coder-note.en-name=sunocdernote
  • sun-coder-note.en_name=sunocdernote
  • sun-coder-note.EN_NAME=sunocdernote

如果这样取值 @Value("${sun-coder-note.enName}") ,你会发现不仅取不到值,还会报错。

虽然松散绑定提供了很大的灵活性,但在实际应用中,建议尽量保持配置文件中的命名风格一致,以便更容易地理解和维护配置文件。

元数据支持

所谓元数据指的是在项目使用了 @ConfigurationProperties 注解时,在编译过程中由 SpringBoot 自动生成的文件的 spring-configuration-metadata.json文件。该元数据文件主要用于为应用程序中的配置文件( application.propertiesapplication.yml)属性提供详细的元数据信息,如属性的名称、数据类型、描述、默认值和废弃信息等。

下面用一个简单示例演示一下元数据的生成:

  1. 引入 spring-boot-configuration-processor Springboot版本是3.1.5 ,,不引入不会生成元数据文件
<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
  1. 编译项目
    项目编译完成之后,在META-INF文件夹下可以看到 spring-configuration-metadata.json

具体格式如下:

{
  "groups": [
    {
      "name": "sun-coder-note",
      "type": "site.suncodernote.properties.SunCoderNoteProperties",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    }
  ],
  "properties": [
    {
      "name": "sun-coder-note.article",
      "type": "site.suncodernote.properties.ArticleProperties",
      "description": "文章",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    },
    {
      "name": "sun-coder-note.en-name",
      "type": "java.lang.String",
      "description": "英文名",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    },
    {
      "name": "sun-coder-note.fans-count",
      "type": "java.lang.Integer",
      "description": "粉丝数",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    },
    {
      "name": "sun-coder-note.name",
      "type": "java.lang.String",
      "description": "中文名",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    },
    {
      "name": "sun-coder-note.read-count",
      "type": "java.lang.Integer",
      "description": "阅读数",
      "sourceType": "site.suncodernote.properties.SunCoderNoteProperties"
    }
  ],
  "hints": []
}

SpEL表达式

SpEL表达式(Spring Expression Language) 是Spring框架中提供的一种强大的表达式语言,它用于在运行时查询和操作对象。

下面举个简单的示例看下 @Value 注解结合SpEL表达式的使用:

@Data
@Configuration
public class SunCoderNoteValueProperties {

    /**
     * 如果sun-coder-note.name自定义属性不存在,设置name默认值为suncodernote
     */
    @Value("${sun-coder-note.name:suncodernote}")
    private String name;

    /**
     *  enName属性的值取site.suncodernote.validation.GenderEnum枚举类的MALE常量的name值
     */
    @Value("#{T(site.suncodernote.validation.GenderEnum).MALE.name()}")
    private String enName;


    /**
     * 如果sun-coder-note.fansCount的值小于1000,就让该值等于10,否则取该值
     */
    @Value("#{${sun-coder-note.fansCount} < 1000 ? 10 : ${sun-coder-note.fansCount}}")
    private Integer fansCount;

    @Value("${sun-coder-note.read-count}")
    private Integer readCount;
}

JSR-303 数据校验

之前的文章《初探Springboot 参数校验》中有介绍参数校验,感兴趣的可以去看看。

@ConfigurationProperties 注解标记的配置类中也是支持参数校验的,只需要在 @Validated ,然后在对应的属性上加上要约束的注解即可。

@Data
@Configuration
@ConfigurationProperties(prefix = "sun-coder-note")
@Validated
public class SunCoderNoteProperties {}

以上就是 @ConfigurationProperties@Value 的区别。

总结

如果需要注入大量相关配置项,并且这些配置项有嵌套的结构或者集合形式,推荐使用 @ConfigurationProperties
如果只是少量的配置项,或者希望使用SpEL表达式时,可以使用 @Value注解。


标签:coder,name,sun,Value,note,ConfigurationProperties,VS
From: https://blog.51cto.com/codersun/11960835

相关文章

  • SciTech-Mathmatics-Probability+Statistics: Differences: Population VS Sampling(D
    SciTech-Mathmatics-Probability+Statistics:Differences:PopulationVSSampling(DistributionofParameters)Likelyhood(Assumption)VSProbability(ModelofSolidParameters)Likelihoodvs.Probability:What'stheDifference?BYZACHBOBBITTPOSTEDONAU......
  • 解决vscode终端输出中文乱码问题图文教程
    由于系统终端默认编码为GBK,所以需要修改为UTF-8方法一打开cmd输入chcp查看编码格式,查看以及修改如下图所示:方法二        ......
  • Android中VSYNC代表什么
    在Android中,VSYNC(VerticalSynchronization)是一个垂直同步信号,用于协调显示刷新和绘图操作。VSYNC信号的主要作用是控制屏幕刷新频率与图形渲染的同步,以确保画面显示平滑且没有撕裂现象。VSYNC的工作原理显示刷新周期:屏幕的刷新率(通常为60Hz)决定了每秒可以更新的帧数。每......
  • 文心一言 VS 讯飞星火 VS chatgpt (342)-- 算法导论23.2 1题
    一、对于同一个输入图,Kruskal算法返回的最小生成树可以不同。这种不同来源于对边进行排序时,对权重相同的边进行的不同处理。证明:对于图G的每棵最小生成树T,都存在一种办法来对G的边进行排序,使得Kruskal算法所返回的最小生成树就是T。如果要写代码,请用go语言。文心一言:证明为了证明对......
  • 【H2O2|全栈】关于VS code你不得不知道的一些事(一)【前端 · 编辑器使用】
    目录VScode便捷使用(一)【随笔】前言插件在哪里下载插件?中文简体(汉化包)Markdown文件编辑HTML快速添加双标签HTML快速修改双标签WEB网页编辑效果实时预览 WEB网页快速浏览器打开WEB网页编辑器服务端口打开 浏览器启动插件(两个)本期汇总预告和回顾后话VScode......
  • [运维][vCenter]VMware vSphere ESXi + vCenter全套软件虚拟机 v6.7详细安装教程
    VMwarevSphere是一套业内最完整最强健的虚拟化平台。创建资源池来管理计算、网络和存储容量与易用性,并提供最高水平的服务,每个应用程序工作负载以最低的总成本。VSphere取决于世界上要求最苛刻的数据中心虚拟化您业务关键型应用程序为空前的灵活性和可靠性。ps:由于文件过......
  • VS Code 快速输入代码
    VSCode快速输入代码:HTML代码 只输入!,按Enter,这将自动生成一个基本的HTML骨架代码,例如: 快速输入特定的HTML标签,可以使用Emmet插件,它是VSCode的一个扩展,可以通过简短的指令生成复杂的HTML结构。输入div,按Enter输入div*4,按Enter 例如,输入ul>li*4将生成一个包......
  • 在VScode-SSH中Rust工程不能代码间跳转的原因
    今天正常使用VScode-SSH访问虚拟机,但是发现读代码的时候不能使用ctrl+左键的方式跳转,然后看到Rust-Analyzer(VScode的Rust语言插件)报错.2024-09-08T02:25:28.998500ZERRORfailedtofindanyprojectsin[AbsPathBuf("/home/winddevil/App")]2024-09-08T02:25:29.002582Z......
  • VsCode+WSL2+Python3+git机器学习环境安装
    安装VsCode,添加WSL扩展插件用管理员权限打开PowerShellwsl--install此命令将启用运行WSL并安装Linux的Ubuntu发行版所需的功能wsl--set-version<distroname>2命令将替换为要更新的Linux发行版的名称,如wsl--set-versionUbuntu2会将Ubuntu设置为使用WSL2......
  • vscode中使用go环境配置细节
    1、在docker容器中下载了go的sdk2、在/etc/profile.d/go.sh里填入如下内容:#!/bin/bashexportGOROOT=/home/ud_dev/goexportPATH=$GOROOT/bin:$PATH 3、设置goenvgoenv-wGOPROXY=https://goproxy.cn,directgoenv-wGO111MODULE=on4、重启这个容器,使得vscode......