《后端程序猿 · @Value 注释说明》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍
文章目录
- 写在前面的话
- SB 读取配置的方式
- @Value 知识扩展
- 三种方式用法
- 集合与Map注入
- 配合 @PropertySource
- 使用的注意事项
- 源码简单分析
- 总结陈词
写在前面的话
Java 程序猿在面向 SpringBoot 开发的时候,读取配置文件信息是一个日常需求,@Value 应该屡见不鲜了,这边对知识做一个汇总,方便查阅。
Tips:近期在更新
程序猿入职必会
系列(还在进行中),先更换一个知识点,调剂一下,每天都有新东西。
系列文章:
《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》
《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》
SB 读取配置的方式
先看一下基础知识,SpringBoot 开发中,需要读取application.yml
或Nacos
上的配置信息,可以使用下面两种方式。
方式一,使用@Value读取
配置属性,使用@Value(“${my.name}”)方式注入成员变量,@Value是实现把配置文件的单个属性的提取。
属性若不存在,启动时候就会报错,如下所示:
为防止这种情况,可以指定默认值,例如:
@Value("${system.defaultReply:不能识别的信息}")
private String defaultReply;@Value("${sql.maxRow:1000}")
private String maxRow;//#{SPEL} Spring表达式
@Value("#{11*2}") // 字面量
@Value("true")
Tips:添加上冒号代表后面是默认值,冒号后面是空的代表空字符串,推荐都加上,否则生产环境差异会导致异常。。
方式二,使用 @ConfigurationProperties 绑定实体
@Value 仅适合单个属性的情况,如果属性很多建议用绑定实体的方式。
@ConfigurationProperties可以实现把配置文件的某前缀开始的key自动映射为实体的初值。
1、添加相应的配置文件信息
ali:oss:accessKeyId: LTAI4FhYdxC7YY8RR6shfXjkaccessKeySecret: LmVvWUJCQzdQpJyX621Xnf43GasQDObucketName: cjwmy1013endPoint: oss-cn-beijing.aliyuncs.comfileHost: https://cjwmy1013.oss-cn-beijing.aliyuncs.com/
2、新建一个实体,和配置文件对应,如下:
@Component
@ConfigurationProperties(prefix = "ali.oss")
@Data
public class AliOSSProperties {private String accessKeyId;private String accessKeySecret;private String endPoint;private String bucketName;private String fileHost;
}
3、注入实体使用。
@Autowired
private AliOSSProperties aliOss;
4、引入 configuration-processor 依赖,这样绑定后可以有提示,也可以跳转,如下:
<!-- 配置文件对应 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
补充,配置文件和属性不匹配也不会报错,需要校验,可以添加@Validated和@NotNull注解,如下:
@ConfigurationProperties(prefix = "author")
@Validated
@Component
public class AuthorBean {@NotNullprivate String name;
}
@Value 知识扩展
@Value属于 Spring 的注解,在spring-beans包下,可以在字段、方法参数、构造函数参数等上面使用,通常用于属性注入,支持 SpEL 表达式来注入值,同时也支持属性占位符注入值。
三种方式用法
1、配置文件读取值
这个也是最常见的,从配置文件读取值,即application.yml 或 application.properties
。
和前面介绍的一样,建议添加上一个默认值,否则配置不存在会报错。
@Value("${spring.application.name:}")
private String name;
2、直接赋值
直接注入字符串,有点类似于直接给属性赋值一样,感觉多此一举,实际开发当中这种应用场景非常少。
@Value("战神")
private String name;
3、SpEl 表达式赋值
#{} 方式表示 SpEl 表达式,通常用来注入Bean对象。
还有很多强大的用法,可以自行掌握。
@Component
public class MyService {@Value("#{myBean}")private MyBean myBean;
}@Component
public class MyBean {// ...
}
集合与Map注入
test:array: aaa,bbb,cccmap: '{"name": "zhangsan", "sex": "male"}'
// 数组
@Value("${test.array:}")
private String[] array1;// 集合
@Value("${test.array:}")
private List<String> list1;// Map
@Value("#{${test.map}}")
private Map<String,String> map1;
配合 @PropertySource
Springboot 默认读取的都是 application.yml 或 application.properties,但是有时候我们想把一些配置给独立起来,这时候可以采用@PropertySource。
@Component
@PropertySource(value = "demo.properties")
public class ReadByProperty {@Value("${demo.name}")private String name;
}
使用的注意事项
使用@Value前提:
1、不能直接作用于静态变量(static);
2、不能直接作用于常量(final);
3、不能在非注册的类中使用(类需要被注册在spring上下文中,如用@Service,@RestController,@Component等);
4、使用这个类时,只能通过依赖注入的方式,用new的方式是不会自动注入这些配置的。
静态变量注入:
使用 @Value 注解是不允许在 static 变量注入的,包括 get 方法也是,直接会获取 null 值。
原因很简单,@Value 围绕的是注入到spring容器当中的这个单例对象,而 static 是类变量,所以肯定不可以的。可以理解为 类变量初始化优先于 Spring 对象注入,所以他无法注入进去。
解决方案可以通过方法注入,或者通过@PostConstruct等初始化逻辑注入,总之就是简洁注入。
@Configuration
public class MyConfig {public static String name;@Value("${spring.application.name}")public void initName(String param) {name = param;}
}
@Configuration
public class MyConfig {public static String name;@Value("${spring.application.name}")private String param;@PostConstructpublic void init(){name = param;}
}
源码简单分析
以下面代码为例,值是怎么设置进去的呢?
@Value("${spring.application.name:}")
private String authorName;
@Value 实际上是通过 org.springframework.beans.factory.config.BeanPostProcessor 来执行的,实际负责做事的是其实现类 AutowiredAnnotationBeanPostProcessor,它负责检查是否有这个注解的存在。
看一下源码,追踪入口是 AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement#inject
(这里九曲十八弯,过程省略)DefaultListableBeanFactory 当中的 doResolveDependency 方法,通过表达式得到真正的值,不同方式的获取逻辑略有差异。
最后将得到的值,通过反射Field的set赋值。
Tips:由于本篇文章不是专门的源码分析篇,简单介绍一下定位方式,源码还是要自己动手看来得真切。
总结陈词
此篇文章介绍了@Value
在项目中得常见用法,仅供学习参考。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。
相关文章:

《后端程序猿 · @Value 注释说明》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

【LeetCode】71.简化路径
1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码: class Solution:def simplifyPath(self, path: str) -> str:operator [] # 操作符的栈dir_name [] # 文件名的栈idx 0cur_dir_name ""while(idx < len(path)):if path[idx] /:operator.ap…...
DockerCompose 安装环境
1. Redis version: 3 services:redis:image: redis:6.2.12container_name: redisports:- "6379:6379"environment:TZ: Asia/Shanghaivolumes:# 本地数据目录要先执行 chmod 777 /usr/local/docker/redis/data 赋予读写权限,否则将无法写入数据- /usr/loc…...

学习笔记之JAVA篇(0724)
p 方法 方法声明格式: [修饰符1 修饰符2 ...] 返回值类型 方法名(形式参数列表){ java语句;......; } 方法调用方式 普通方法对象.方法名(实参列表)静态方法类名.方法名(实参列表) 方法的详…...

【Android】广播机制
【Android】广播机制 前言 广播机制是Android中一种非常重要的通信机制,用于在应用程序之间或应用程序的不同组件之间传递信息。广播可以是系统广播,也可以是自定义广播。广播机制主要包括标准广播和有序广播两种类型。 简介 在Android中,…...
【.NET全栈】ASP.NET开发Web应用——ASP.NET数据绑定技术
文章目录 前言一、绑定技术基础1、单值绑定2、重复值绑定 二、数据源控件1、数据绑定的页面生存周期2、SqlDataSource3、使用参数过滤数据4、更新数据和并发处理5、编程执行SqlDataSource命令6、ObjectDataSource控件介绍7、创建业务对象类8、在ObiectDataSource中使用参数9、使…...

MySQL的账户管理
目录 1 密码策略 1.1 查看数据库当前密码策略: 1.2 查看密码设置策略 1.3 密码强度检查等级解释(validate_password.policy) 2 新建登录账户 3 账户授权 3.1 赋权原则 3.2 常见的用户权限 3.3 查看权限 3.4 赋权语法 4 实例 4.1 示例1&#x…...

FastGPT 源码调试配置
目录 一、添加 launch.json 文件 二、调试 本文简单介绍如何通过 vscode 对 FastGPT 进行调试。 这里假设已经安装 vsocde 和 FastGPT本地部署。 一、添加 launch.json 文件 vscode 打开 FastGPT 项目,点击 调试 -> 显示所有自动调试配置 -> 添加配置 -> Node.j…...
SQL Server数据迁移新纪元:数据库数据泵(Data Pump)使用指南
SQL Server数据迁移新纪元:数据库数据泵(Data Pump)使用指南 在数据管理的世界里,数据迁移是一个常见且复杂的过程。SQL Server提供了一个强大的工具——数据库数据泵(Data Pump),它可以帮助我…...
Android性能优化之OOM
OOM 什么是OOM?为什么会有OOM?APP的内存限制App的内存限制是多少? 为什么Android系统要设定App的内存限制?Android有GC自动回收资源,为什么还会OOM?容易发生OOM的场景及处理方案如何避免OOM? 什么是OOM&am…...

代码随想录算法训练营day7 | 454.四数相加II、383.赎金信、15.三数之和、18.四数之和
文章目录 454.四数相加II思路 383.赎金信思路 15.三数之和思路剪枝去重 18.四数之和思路剪枝去重复习:C中的类型转换方法 总结 今天是哈希表专题的第二天 废话不多说,直接上题目 454.四数相加II 建议:本题是 使用map 巧妙解决的问题&#x…...

Spark实时(三):Structured Streaming入门案例
文章目录 Structured Streaming入门案例 一、Scala代码如下 二、Java 代码如下 三、以上代码注意点如下 Structured Streaming入门案例 我们使用Structured Streaming来监控socket数据统计WordCount。这里我们使用Spark版本为3.4.3版本,首先在Maven pom文件中导…...

《Java初阶数据结构》----4.<线性表---Stack栈和Queue队列>
前言 大家好,我目前在学习java。之前也学了一段时间,但是没有发布博客。时间过的真的很快。我会利用好这个暑假,来复习之前学过的内容,并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…...
Android SurfaceFlinger——关联EGL三要素(二十七)
通过前面的文章我们得到了 EGL 的三要素——Display、Surface 和 Context。其中,Display 是一个图形显示系统或者硬件屏幕,Surface 代表一个可以被渲染的图像缓冲区,Context 包含了 OpenGL ES 的状态信息和资源,它是执行 OpenGL 命令的环境。下一步就是调用 eglMakeCurrent…...

Unity3D之TCP网络通信(客户端)
文章目录 概述TCP核心类异步机制 Unity中创建TCP客户端Unity中其它脚本获取TCP客户端接受到的数据后续改进 本文将以Unity3D应用项目作为客户端去连接制定的服务器为例进行相关说明。 Unity官网参考资料: https://developer.unity.cn/projects/6572ea1bedbc2a001ef…...
Kotlin 中 标准库函数
在 Kotlin 中,标准库提供了许多实用的函数,这些函数可以帮助简化代码、提高效率,以下是一些常用的标准库函数及其功能: let: let 函数允许你在对象上执行一个操作,并返回结果。它通常与安全调用操作符 ?. 一起使用&a…...

【教学类-69-01】20240721铠甲勇士扑克牌(随机14个数字+字母)涂色(男孩篇)
背景需求: 【教学类-68-01】20240720裙子涂色(女孩篇)-CSDN博客文章浏览阅读250次。【教学类-68-01】20240720裙子涂色(女孩篇)https://blog.csdn.net/reasonsummer/article/details/140578153 前期制作了女孩涂色延…...

Adobe“加速”创意人士开启设计新篇章
近日,Adobe公司宣布了其行业领先的专业设计应用程序——Adobe Illustrator和Adobe Photoshop的突破性创新。这一重大更新不仅为创意专业人士带来了前所未有的设计可能性和工作效率提升,还让不论是插画师、设计师还是摄影师,都能从中受益并创作…...

释疑 803-(1)概述 精炼提纯版
目录 习题 1-01计算机网络可以向用户提供哪些服务? 1-02 试简述分组交换的要点。 1-03 试从多个方面比较电路交换、报文交换和分组交换的主要优缺点。 1-05 互联网基础结构的发展大致分为哪几个阶段?请指出这几个阶段最主要的特点。 1-06 简述互联网标准制定的几个阶段…...

人工智能与机器学习原理精解【6】
文章目录 数值优化基础理论凹凸性定义在国外与国内存在不同国内定义国外定义总结示例与说明注意事项 国内凹凸性二阶定义的例子凹函数例子凸函数例子 凸函数(convex function)的开口方向凸函数的二阶导数凸函数的二阶定义单变量函数的二阶定义多变量函数…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...