Spring博文
我真的很小心了,但还是被 SpringEvent 坑了!
网上被吹爆的Spring Event事件订阅有缺陷,一个月内我被坑了两次!
@ConfigurationProperties VS @Value,你觉得哪个更好用 - 掘金
一个注解就搞定接口统一返回、统一异常处理、加签、验签、加密、解密
SpringBoot3 优雅集成 Knife4j - 掘金
Spring Boot 3.x 中的 RestClient 使用案例-Spring专区论坛-技术-SpringForAll社区
Maven项目Parent,可以试试用这个代替 Spring Boot Parent
SpringBoot集成Logback终极指南:从控制台到云端的多维日志输出
Knife4j:实时接口文档的利器
Spring Boot的Docker Layer优化:缩小镜像体积并提升启动速度-Spring专区论坛-技术-SpringForAll社区
使用Prometheus和Grafana监控Spring Boot应用
Spring Boot 4 新特性详解:5大核心更新助力企业级开发
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
SpringBoot + SpringCloud Gateway + Sentinel + Redis:API 网关层的接口限流、黑名单拦截与用户认证
SpringBoot + Seata + MySQL + RabbitMQ:金融系统分布式交易对账与资金清算实战
SpringBoot + MyBatis-Plus + Elasticsearch + MySQL:电商商品搜索关键词高亮与库存实时展示
SpringBoot + RabbitMQ + MySQL + XXL-Job:物流系统运单状态定时同步与异常订单重试
本文档使用 MrDoc 发布
-
+
@ConfigurationProperties VS @Value,你觉得哪个更好用 - 掘金
实际工作中,我们经常会看到或用到`@ConfigurationProperties`和`@Value` 注解来注入自定义配置属性,那它们之间有什么不同呢?本文将从松散绑定 、参数校验、SpEL表达式、元数据支持等多方面介绍两者之间的不同之处。 ## 使用 先看一下怎么使用它们。 ```bash 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** 注解接收自定义属性 ```java public class SunCoderNoteProperties { private String name; private String enName; private Integer fansCount; private Integer readCount; private ArticleProperties article; } ``` 通常情况下,在使用 **@ConfigurationProperties** 注解时,只要指定**prefix**前缀属性即可,同时 **@Configuration** 也要一起使用,要不然Springboot识别不到自定义的属性。 在属性上使用 **@Value** 注解 ,使用 **$** 符号直接获取自定义属性名对应的值。 ```java public class SunCoderNoteValueProperties { private String name; private String enName; private Integer fansCount; private Integer readCount; } ``` ## 测试 上面两个属性类定义好后,通过单元测试,测试能否获取到值。 ```java class PropertiesApplicationTests { private SunCoderNoteProperties sunCoderNoteProperties; private SunCoderNoteValueProperties sunCoderNoteValueProperties; public void testBean(){ System.out.println(sunCoderNoteProperties); System.out.println(); System.out.println(sunCoderNoteValueProperties); } } ``` 通过测试,查看控制台,可以看到两种方式都能够获取到对应的属性值。 ```text 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.properties` 或 `application.yml`)属性提供详细的元数据信息,如属性的名称、数据类型、描述、默认值和废弃信息等。 下面用一个简单示例演示一下元数据的生成: 1. 引入 `spring-boot-configuration-processor` Springboot版本是**3.1.5** ,,不引入不会生成元数据文件 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> ``` 1. 编译项目 项目编译完成之后,在**META-INF**文件夹下可以看到 `spring-configuration-metadata.json`  具体格式如下: ```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表达式**的使用: ```java public class SunCoderNoteValueProperties { private String name; private String enName; private Integer fansCount; private Integer readCount; } ``` ## JSR-303 数据校验 之前的文章《[初探Springboot 参数校验](https://juejin.cn/post/7344325496984174618)》中有介绍参数校验,感兴趣的可以去看看。 `@ConfigurationProperties` 注解标记的配置类中也是支持参数校验的,只需要在 **@Validated** ,然后在对应的属性上加上要约束的注解即可。 ```java public class SunCoderNoteProperties {} ``` 以上就是 **@ConfigurationProperties** 和 **@Value** 的区别。 ## 总结 如果需要注入大量相关配置项,并且这些配置项有嵌套的结构或者集合形式,推荐使用 **@ConfigurationProperties**。 如果只是少量的配置项,或者希望使用**SpEL表达式**时,可以使用 **@Value**注解。
admin
2024年7月28日 07:09
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码