当前位置: 首页 > news >正文

《后端程序猿 · @Value 注释说明》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • SB 读取配置的方式
    • @Value 知识扩展
      • 三种方式用法
      • 集合与Map注入
      • 配合 @PropertySource
      • 使用的注意事项
      • 源码简单分析
    • 总结陈词

CSDN.gif

写在前面的话

Java 程序猿在面向 SpringBoot 开发的时候,读取配置文件信息是一个日常需求,@Value 应该屡见不鲜了,这边对知识做一个汇总,方便查阅。

Tips:近期在更新程序猿入职必会系列(还在进行中),先更换一个知识点,调剂一下,每天都有新东西。

系列文章:
《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》
《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》


SB 读取配置的方式

先看一下基础知识,SpringBoot 开发中,需要读取application.ymlNacos上的配置信息,可以使用下面两种方式。

方式一,使用@Value读取
配置属性,使用@Value(“${my.name}”)方式注入成员变量,@Value是实现把配置文件的单个属性的提取。
属性若不存在,启动时候就会报错,如下所示:
image.png
为防止这种情况,可以指定默认值,例如:

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

image.png


配合 @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
image.png
(这里九曲十八弯,过程省略)DefaultListableBeanFactory 当中的 doResolveDependency 方法,通过表达式得到真正的值,不同方式的获取逻辑略有差异。
image.png
最后将得到的值,通过反射Field的set赋值。
image.png

Tips:由于本篇文章不是专门的源码分析篇,简单介绍一下定位方式,源码还是要自己动手看来得真切。


总结陈词

此篇文章介绍了@Value在项目中得常见用法,仅供学习参考。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

CSDN_END.gif

相关文章:

《后端程序猿 · @Value 注释说明》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

【LeetCode】71.简化路径

1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码&#xff1a; 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 赋予读写权限&#xff0c;否则将无法写入数据- /usr/loc…...

学习笔记之JAVA篇(0724)

p 方法 方法声明格式&#xff1a; [修饰符1 修饰符2 ...] 返回值类型 方法名&#xff08;形式参数列表&#xff09;{ java语句;......; } 方法调用方式 普通方法对象.方法名&#xff08;实参列表&#xff09;静态方法类名.方法名&#xff08;实参列表&#xff09; 方法的详…...

【Android】广播机制

【Android】广播机制 前言 广播机制是Android中一种非常重要的通信机制&#xff0c;用于在应用程序之间或应用程序的不同组件之间传递信息。广播可以是系统广播&#xff0c;也可以是自定义广播。广播机制主要包括标准广播和有序广播两种类型。 简介 在Android中&#xff0c…...

【.NET全栈】ASP.NET开发Web应用——ASP.NET数据绑定技术

文章目录 前言一、绑定技术基础1、单值绑定2、重复值绑定 二、数据源控件1、数据绑定的页面生存周期2、SqlDataSource3、使用参数过滤数据4、更新数据和并发处理5、编程执行SqlDataSource命令6、ObjectDataSource控件介绍7、创建业务对象类8、在ObiectDataSource中使用参数9、使…...

MySQL的账户管理

目录 1 密码策略 1.1 查看数据库当前密码策略&#xff1a; 1.2 查看密码设置策略 1.3 密码强度检查等级解释&#xff08;validate_password.policy&#xff09; 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数据迁移新纪元&#xff1a;数据库数据泵&#xff08;Data Pump&#xff09;使用指南 在数据管理的世界里&#xff0c;数据迁移是一个常见且复杂的过程。SQL Server提供了一个强大的工具——数据库数据泵&#xff08;Data Pump&#xff09;&#xff0c;它可以帮助我…...

Android性能优化之OOM

OOM 什么是OOM&#xff1f;为什么会有OOM&#xff1f;APP的内存限制App的内存限制是多少&#xff1f; 为什么Android系统要设定App的内存限制&#xff1f;Android有GC自动回收资源&#xff0c;为什么还会OOM?容易发生OOM的场景及处理方案如何避免OOM&#xff1f; 什么是OOM&am…...

代码随想录算法训练营day7 | 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

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

Spark实时(三):Structured Streaming入门案例

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

《Java初阶数据结构》----4.<线性表---Stack栈和Queue队列>

前言 大家好&#xff0c;我目前在学习java。之前也学了一段时间&#xff0c;但是没有发布博客。时间过的真的很快。我会利用好这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…...

Android SurfaceFlinger——关联EGL三要素(二十七)

通过前面的文章我们得到了 EGL 的三要素——Display、Surface 和 Context。其中,Display 是一个图形显示系统或者硬件屏幕,Surface 代表一个可以被渲染的图像缓冲区,Context 包含了 OpenGL ES 的状态信息和资源,它是执行 OpenGL 命令的环境。下一步就是调用 eglMakeCurrent…...

Unity3D之TCP网络通信(客户端)

文章目录 概述TCP核心类异步机制 Unity中创建TCP客户端Unity中其它脚本获取TCP客户端接受到的数据后续改进 本文将以Unity3D应用项目作为客户端去连接制定的服务器为例进行相关说明。 Unity官网参考资料&#xff1a; https://developer.unity.cn/projects/6572ea1bedbc2a001ef…...

Kotlin 中 标准库函数

在 Kotlin 中&#xff0c;标准库提供了许多实用的函数&#xff0c;这些函数可以帮助简化代码、提高效率&#xff0c;以下是一些常用的标准库函数及其功能&#xff1a; let: let 函数允许你在对象上执行一个操作&#xff0c;并返回结果。它通常与安全调用操作符 ?. 一起使用&a…...

【教学类-69-01】20240721铠甲勇士扑克牌(随机14个数字+字母)涂色(男孩篇)

背景需求&#xff1a; 【教学类-68-01】20240720裙子涂色&#xff08;女孩篇&#xff09;-CSDN博客文章浏览阅读250次。【教学类-68-01】20240720裙子涂色&#xff08;女孩篇&#xff09;https://blog.csdn.net/reasonsummer/article/details/140578153 前期制作了女孩涂色延…...

Adobe“加速”创意人士开启设计新篇章

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

释疑 803-(1)概述 精炼提纯版

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

人工智能与机器学习原理精解【6】

文章目录 数值优化基础理论凹凸性定义在国外与国内存在不同国内定义国外定义总结示例与说明注意事项 国内凹凸性二阶定义的例子凹函数例子凸函数例子 凸函数&#xff08;convex function&#xff09;的开口方向凸函数的二阶导数凸函数的二阶定义单变量函数的二阶定义多变量函数…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...