《后端程序猿 · @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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1487398.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SQL labs-SQL注入(四,sqlmap对于post传参方式的注入)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 序言&#xff1a;本文主要讲解基于SQL labs靶场&#xff0c;sqlmap工具进行的post传参方式的SQL注入。 传参方式有两类&#xff0c;一类是直接在url栏内进行url编码后进行的传参&am…

Android APK混淆处理方案分析

这里写目录标题 一、前言1.1 相关工具二、Apk 分析2.1 apk 解压文件2.2 apk 签名信息2.3 apk AndroidManifest.xml2.4 apk code三、Apk 处理3.1 添加垃圾文件3.2 AndroidManifest.xml 处理3.3 dex 混淆处理3.4 zipalign对齐3.5 apk 重新签名3.6 apk 安装测试四、总结一、前言 提…

sentinel 服务流量控制 、熔断降级

1、什么是 sentinel,可以用来干什么 sentinel是用来在微服务系统中保护微服务对的作用,如何避免服务的雪崩、熔断、降级,说白了就是用来替换hystrix。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 官网:GitHub - alibaba/Se…

Ubuntu安装QQ教程

Ubuntu安装QQ教程 腾讯更新Linux版的QQ&#xff0c;这里安装一下&#xff1b; 首先&#xff0c;进入官网找到合适对应的安装包&#xff1b; QQLinux版本官网&#xff1a;https://im.qq.com/linuxqq/index.shtml 我们是ubuntu系统选择X86下的deb版本&#xff0c;如果是arm开…

5G单北斗定位工卡

UWB卫星定位工卡&#xff08;HXZK-UBK&#xff09;融合定位系统结合了两种定位技术的优势&#xff0c;从而能够在各种环境下实现更精准、更可靠的定位,UWB&#xff08;ULtra-Wideband&#xff0c;超宽带&#xff09;技术和GNGSS&#xff08;GLobal Positioning System&#xff…

上海浦东装修公司推荐:高端选择,品质生活

在上海浦东这样一个经济繁荣、文化多元的地区&#xff0c;居住环境的品质直接关系到家的感觉。为了追求高品质生活的您&#xff0c;我们精心挑选了五大豪华装修公司。1.即住空间装饰即住空间装饰以其“高效、省心、精工”为核心理念&#xff0c;专注于为追求高品质生活的业主提…

【word转pdf】【最新版本jar】Java使用aspose-words实现word文档转pdf

【aspose-words-22.12-jdk17.jar】word文档转pdf 前置工作1、下载依赖2、安装依赖到本地仓库 项目1、配置pom.xml2、配置许可码文件&#xff08;不配置会有水印&#xff09;3、工具类4、效果 踩坑1、pdf乱码2、word中带有图片转换 前置工作 1、下载依赖 通过百度网盘分享的文…

嵌入式linux系统中压力测试的方法

在Linux环境下,确保系统各项资源充分且稳定地运行对任何系统管理员来说都至关重要。特别是在生产环境中,理解如何对系统资源进行基准测试和压力测试可以帮助预防未来的问题,同时也能够优化现有系统的性能。 在本文中,我们将探讨如何使用命令行工具来对Linux系统的CPU、内存…

科技前沿:Llama 3.1的突破与革新

在科技的长河中&#xff0c;每一次模型的更新都是对人类智慧的致敬。今天&#xff0c;我们将聚焦于Meta公司最新发布的Llama 3.1系列模型&#xff0c;探索其在AI领域的前沿突破。 新模型的诞生 自去年以来&#xff0c;Meta公司不断推进人工智能技术的发展&#xff0c;终于在近…

2024软件测试面试题及答案

【纯干货&#xff01;&#xff01;&#xff01;】花费了整整3天&#xff0c;整理出来的全网最实用软件测试面试大全&#xff0c;一共30道题目答案的纯干货&#xff0c;希望大家多多支持&#xff0c;建议 点赞&#xff01;&#xff01;收藏&#xff01;&#xff01;长文警告&…

学习华为IPD流程黑话2.0

目录 1、内容简介 2、概念六&#xff1a;管道管理 3、概念七&#xff1a;业务计划 4、概念八&#xff1a;IPMT 的投资活动 5、概念九&#xff1a;BETA、ESS、ESP 作者简介 1、内容简介 学习任何新事物都是从概念开始的。 以我个人最近遇到的一个事为例&#xff1a; 前…

双向链表(C语言版)

1. 双向链表的结构 注意&#xff1a;这里的“带头”跟单链表的“头结点”是两个概念&#xff0c;实际上在单链表阶段称呼不太严谨&#xff0c;但是为了更好地理解就直接称为单链表的头结点。带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有…

运维锅总浅析网络攻击与防范

本文介绍常见的网络攻击手法及防御措施&#xff0c;并进一步介绍如何进行安全教育和培训、攻击溯源。希望对您提高网络安全防范意识有所帮助&#xff01; 一、常见的网络攻击手法 网络攻击手法多种多样&#xff0c;以下是一些常见的网络攻击手法及其基本原理&#xff1a; 1.…

vue 两个页面切换, 再回到当前页,还是离开前的数据

1、要保证页面的name 和 建路由的大小写一致 2、页面不用生命周期--activated 调接口刷新

嵌入式系统上通过crontab表达式实现基于绝对时间的秒级定时任务

摘要 在嵌入式系统开发中&#xff0c;定时任务是确保系统按预定计划正确执行功能的关键。通过结合 crontab 表达式和 C 语言&#xff0c;可以设计出精准且灵活的定时任务系统。本博客详细描述了如何在嵌入式开发中&#xff0c;使用 crontab 表达式来实现基于绝对时间的定时任务…

农业农村大数据底座:实现智慧农业的关键功能

随着信息技术的快速发展&#xff0c;农业领域也在逐步实现数字化转型。农业农村大数据底座作为支持智慧农业发展的重要基础设施&#xff0c;承载了多种关键功能&#xff0c;为农业生产、管理和决策提供了前所未有的支持和可能性。 ### 1. 数据采集与监测 农业农村大数据底座首…

鸿蒙OpenHarmony Native API【NativeWindow】

NativeWindow Overview Description: 提供NativeWindow功能&#xff0c;主要用来和egl对接 syscap SystemCapability.Graphic.Graphic2D.NativeWindow Since: 8 Version: 1.0 Summary Files File NameDescription[external_window.h]定义获取和使用NativeWindow的相…

百度网盘批量转存程序

百度网盘批量转存程序&#xff0c;基于 Python 3.10 Tkinter 构建&#xff0c;主要用于批量转存网络上分享的资源到自己的百度网盘。此外还带有批量分享和批量检测链接有效性的功能。 程序主界面&#xff1a; 下载地址&#xff1a;https://pan.quark.cn/s/c739ee25b238

【算法专题】链表算法题

1. 链表常用操作 相信大家在学习数据结构的过程中已经接触过许多链表相关的题目了&#xff0c;在正式开始刷题之前&#xff0c;我想让大家先回顾一下过去处理链表相关问题时的一些常见操作。 首先肯定就是创建新节点了&#xff0c;如果使用C语言编写代码&#xff0c;我…

Mac m1安装 MongoDB 7.0.12

一、下载MongoDB MongoDB 社区版官网下载 二、安装配置MongoDB 1.解压下载的压缩包文件&#xff0c;文件夹重命名为mongodb; 2.将重命名为mongodb的文件夹&#xff0c;放在/usr/local 目录下 3.在/usr/local/mongodb 目录下&#xff0c;新建data 和 log这两个文件夹&#…