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

深入解析 Spring 中的 @Value 注解(含源码级剖析 + 自定义实现)

深入解析 Spring 中的 @Value 注解(含源码级剖析 + 自定义实现)

在 Spring 开发中,我们经常使用 @Value 注解将配置文件中的值注入到 Bean 的属性中。本文将深入探讨 @Value 的使用方式、默认值支持、底层原理以及自定义实现方式。


一、@Value 的常见用法

@Value("${server.port}")
private int port;@Value("${user.name:defaultUser}")
private String userName;

上面的用法展示了两种典型场景:

  • 从配置文件中读取值:${server.port}
  • 设置默认值:${user.name:defaultUser},当 user.name 不存在时使用 defaultUser

默认值语法说明:

${property:defaultValue}
${property} 不存在或为 null,就使用 defaultValue


二、常见使用场景示例

  1. 注入配置值

    @Value("${spring.datasource.url}")
    private String datasourceUrl;
    
  2. 注入 SpEL 表达式

    @Value("#{2 * 10}")
    private int result;  // 20
    
  3. 注入集合类型

    @Value("#{'${my.list}'.split(',')}")
    private List<String> list;
    

三、@Value 的源码原理解析

注解定义

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {String value();
}

其本身是一个标准注解,用于描述需要注入的值。

核心解析类:AutowiredAnnotationBeanPostProcessor

Spring 中处理 @Value 注入的核心类是 AutowiredAnnotationBeanPostProcessor,其在初始化阶段对属性字段进行处理。

内部依赖了 ValueAnnotationProcessorEnvironment,其关键逻辑:

PropertyResolver resolver = beanFactory.getBean(Environment.class);
String resolvedValue = resolver.resolvePlaceholders("${user.name:defaultUser}");

如果我们设置了默认值 ${user.name:defaultUser},那么当 user.name 不存在时,Spring 使用 defaultUser

Spring 会在容器启动时对这些带有 @Value 的字段进行反射注入,核心逻辑类似:

Field field = clazz.getDeclaredField("userName");
field.setAccessible(true);
field.set(beanInstance, resolvedValue);

四、自定义一个简化版 @MyValue 注解

下面我们模拟实现一个简单版的 @Value 注解,读取配置并注入到 Bean 中。

1. 自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyValue {String value();
}

2. 简单配置文件解析器

public class MyPropertyResolver {private static final Properties props = new Properties();static {try {props.load(MyPropertyResolver.class.getResourceAsStream("/application.properties"));} catch (IOException e) {e.printStackTrace();}}public static String resolve(String keyExpression) {if (keyExpression.startsWith("${") && keyExpression.endsWith("}")) {String expr = keyExpression.substring(2, keyExpression.length() - 1);String[] parts = expr.split(":", 2);String key = parts[0];String defaultValue = parts.length > 1 ? parts[1] : null;return props.getProperty(key, defaultValue);}return keyExpression;}
}

3. 注入处理器

public class MyValueProcessor {public static void inject(Object bean) {Class<?> clazz = bean.getClass();for (Field field : clazz.getDeclaredFields()) {MyValue annotation = field.getAnnotation(MyValue.class);if (annotation != null) {String resolved = MyPropertyResolver.resolve(annotation.value());try {field.setAccessible(true);Object value = convert(field.getType(), resolved);field.set(bean, value);} catch (IllegalAccessException e) {e.printStackTrace();}}}}private static Object convert(Class<?> type, String value) {if (type == int.class) return Integer.parseInt(value);if (type == long.class) return Long.parseLong(value);if (type == boolean.class) return Boolean.parseBoolean(value);return value; // default to String}
}

4. 使用方式

public class UserConfig {@MyValue("${user.age:18}")private int age;@MyValue("${user.name:anonymous}")private String name;public void print() {System.out.println("Name: " + name + ", Age: " + age);}
}
public class Main {public static void main(String[] args) {UserConfig config = new UserConfig();MyValueProcessor.inject(config);config.print();}
}

五、总结

  • @Value 注解是 Spring 中用于注入配置的强大工具,支持 SpEL 和默认值语法。
  • 底层依赖的是 Spring 的环境抽象和 BeanPostProcessor 扩展点。
  • 我们可以通过自定义注解 + 属性解析器 + 反射机制,简单实现类似功能。

相关文章:

深入解析 Spring 中的 @Value 注解(含源码级剖析 + 自定义实现)

深入解析 Spring 中的 Value 注解&#xff08;含源码级剖析 自定义实现&#xff09; 在 Spring 开发中&#xff0c;我们经常使用 Value 注解将配置文件中的值注入到 Bean 的属性中。本文将深入探讨 Value 的使用方式、默认值支持、底层原理以及自定义实现方式。 一、Value 的…...

【Flink SQL实战】 UTC 时区格式的 ISO 时间转东八区时间

文章目录 一、原始数据格式二、解决方案三、其他要求 在实际开发中&#xff0c;我们常常会遇到此类情况&#xff1a;数据源里的时间格式是类似 2025-04-21T09:23:16.025Z 这种带 TimeZone 标识的 ISO 8601 格式&#xff0c;而我们需要在 Flink SQL 中将其转换成北京时间显示。 …...

【论文阅读23】-地下水预测-TCN-LSTM-Attention(2024-11)

这篇论文主要围绕利用深度学习模型检测地下水位异常以识别地震前兆展开。 [1] Chen X, Yang L, Liao X, et al. Groundwater level prediction and earthquake precursor anomaly analysis based on TCN-LSTM-attention network[J]. IEEE Access, 2024, 12: 176696-176718. 期刊…...

/proc/sys/vm/下各参数含义

/proc/sys/vm/下各参数含义 admin_reserve_kbytes如何计算最小有效预留&#xff1f; compact_memorycompaction_proactivenesscompact_unevictable_alloweddirty_background_bytesdirty_background_ratiodirty_bytesdirty_expire_centisecsdirty_ratiodirtytime_expire_seconds…...

算法分析与设计——动态规划复习题(待更新

检测题&#xff1a; 组合优化问题的目标函数通常不包括以下哪种形式&#xff1f; A. 需最小化的代价函数 B. 需最大化的回报函数 C. 需满足的硬约束条件 D. 需最小化的能量函数 答案&#xff1a;C 关于约束条件的说法&#xff0c;以下哪项是正确的&#xff1f; A. 硬约束可以通…...

【EasyPan】项目常见问题解答(自用持续更新中…)

EasyPan 网盘项目介绍 一、项目概述 EasyPan 是一个基于 Vue3 SpringBoot 的网盘系统&#xff0c;支持文件存储、在线预览、分享协作及后台管理&#xff0c;技术栈涵盖主流前后端框架及中间件&#xff08;MySQL、Redis、FFmpeg&#xff09;。 二、核心功能模块 用户认证 注册…...

基于Java的不固定长度字符集在指定宽度和自适应模型下图片绘制生成实战

目录 前言 一、需求介绍 1、指定宽度生成 2、指定列自适应生成 二、Java生成实现 1、公共方法 2、指定宽度生成 3、指定列自适应生成 三、总结 前言 在当今数字化与信息化飞速发展的时代&#xff0c;图像的生成与处理技术正日益成为众多领域关注的焦点。从创意设计到数…...

电子电器架构 ---软件定义汽车的电子/电气(E/E)架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

Stable Diffusion 制作角色三视图

对于漫画创作&#xff0c;DPM 2M Karras和UniPC是高效且稳定的首选采样方法&#xff0c;结合Karras噪声调度可显著提升画面质量。若需进一步优化&#xff0c;可参考具体场景调整步数并辅以ControlNet等工具。避免使用随机性强的采样器&#xff08;如Euler a&#xff09;&#x…...

C++--负载均衡在线OJ

这是本人写的第二个项目&#xff0c;相比第一个代码量更少一些&#xff0c;但是此项目涉及linux中的内容更多&#xff0c;同样是干货满满&#xff0c;实现了 类似 leetcode 的题⽬列表在线编程功能&#xff0c;地址仓库&#xff1a;xwy/C学习项目 1. 所用技术与开发环境 C11和…...

【数字图像处理】彩色图像处理(1)

研究彩色图像处理的原因 1&#xff1a;利用颜色信息&#xff0c;可以简化目标物的区分&#xff0c;以及从场景中提取出目标物 2&#xff1a;人眼对颜色非常敏感&#xff0c;可以分辨出来几千种颜色色调和亮度&#xff0c;却只能分别出几十种灰度 彩色图像分类 伪彩色图像处理&…...

【Easylive】consumes = MediaType.MULTIPART_FORM_DATA_VALUE 与 @RequestPart

【Easylive】项目常见问题解答&#xff08;自用&持续更新中…&#xff09; 汇总版 consumes MediaType.MULTIPART_FORM_DATA_VALUE 的作用 1. 定义请求的数据格式 • 作用&#xff1a;告诉 Feign 和 HTTP 客户端&#xff0c;这个接口 接收的是 multipart/form-data 格式的…...

【python】copy deepcopy 赋值= 对比

上结论 写法是否独立是否安全修改copy() &#xff08;用于一维列表&#xff09;✅ 是独立副本✅ 安全deepcopy() &#xff08;多层结构时用&#xff09;✅ 是完全副本✅ 安全直接赋值&#xff08;&#xff09;❌ 是引用❌ 改一个会影响另一个 一、.copy() 和 deepcopy() 有什…...

环形缓冲区容量耗尽解决方案

以下是针对环形缓冲区在时间窗口统计场景中容量耗尽问题的解决方案设计及优劣分析&#xff0c;结合搜索结果中的技术原理和工程实践&#xff1a; 一、核心问题定位 当环形缓冲区容量耗尽时&#xff0c;新数据覆盖旧数据会导致&#xff1a; 时间窗口统计失真&#xff1a;无法准…...

蓝桥杯 17.发现环

发现环 原题目链接 题目描述 小明的实验室有 N 台电脑&#xff0c;编号 1 ⋯ N。 原本这 N 台电脑之间有 N−1 条数据链接相连&#xff0c;恰好构成一个树形网络。 在树形网络上&#xff0c;任意两台电脑之间有唯一的路径相连。 不过在最近一次维护网络时&#xff0c;管理…...

数据库服务器架构

ORM ORM&#xff08;Object Relational Mapping&#xff09;&#xff1a;对象与关系数据之间的映射 映射关系表&#xff1a; 类&#xff08;class&#xff09;—— 数据库的表&#xff08;table&#xff09; 对象&#xff08;object&#xff09;——记录&#xff08;record…...

Netty前置基础知识之BIO、NIO以及AIO理论详细解析和实战案例

前言 Netty是什么&#xff1f; Netty 是一个基于 Java 的 ​高性能异步事件驱动网络应用框架&#xff0c;主要用于快速开发可维护的协议服务器和客户端。它简化了网络编程的复杂性&#xff0c;特别适合构建需要处理海量并发连接、低延迟和高吞吐量的分布式系统。 1)Netty 是…...

职坐标IT培训:人工智能职业跃迁路径

随着人工智能时代全面来临&#xff0c;职业发展格局正经历颠覆性重构。政策端&#xff0c;《新一代人工智能发展规划》与《生成式AI服务管理办法》双轨并行&#xff0c;既为行业注入动能&#xff0c;也划定了技术应用的合规边界。在此背景下&#xff0c;从业者需构建覆盖基础理…...

Redis 的单线程模型对微服务意味着什么?需要注意哪些潜在瓶颈?

Redis 的单线程模型是其高性能的关键因素之一&#xff0c;但这在微服务场景下既是优势&#xff0c;也可能带来潜在的瓶颈。理解这一点有助于我们在微服务架构中更好的使用Redis。 Redis 单线程模型的核心&#xff1a; 命令处理是单线程的: Redis 使用了一个主线程来接收客户端…...

Redis 有序集合(Sorted Set)

Redis 有序集合&#xff08;Sorted Set&#xff09; 以下从基础命令、内部编码和使用场景三个维度对 Redis 有序集合进行详细解析&#xff1a; 一、基础命令 命令时间复杂度命令含义zadd key score member [score member …] O ( k l o g ( n ) ) O(klog(n)) O(klog(n))&…...

C语言中联合体(Union)和结构体(Struct)的嵌套用法

联合体和结构体是C语言中两种重要的复合数据类型&#xff0c;它们可以相互嵌套使用&#xff0c;为复杂数据的表示提供了灵活的方式。 1. 联合体(Union)基础 联合体是一种特殊的数据类型&#xff0c;允许在相同的内存位置存储不同的数据类型。联合体的所有成员共享同一块内存空…...

Rust: 从内存地址信息看内存布局

内存布局其实有几个&#xff1a;address&#xff08;地址&#xff09;、size&#xff08;大小&#xff09;、alignment&#xff08;对齐位数&#xff0c;2 的自然数次幂&#xff0c;2&#xff0c;4&#xff0c;8…&#xff09;。 今天主要从address来看内存的布局。 下面以Str…...

分类算法中one-vs-rest策略和one-vs-one 策略的区别是什么?

LGBMClassifier 参数中&#xff0c;常使用objective: 这个参数定义了模型的目标函数。 而对于多分类问题&#xff0c;通常使用 multiclass 或者 multiclassova。multiclass 表示 one-vs-rest 策略&#xff0c;而 multiclassova 则是 one-vs-one 策略。 在机器学习领域&#x…...

新能源汽车充电桩运营模式的发展与优化路径探析

摘要&#xff1a;以民用新能源汽车充电桩为研究对象&#xff0c;在分析政府主导型、电网企业主导型及汽车厂商主导型三种运营模式特点的基础上&#xff0c;结合我国新能源汽车发展现状&#xff0c;提出汽车厂商与电网企业协同共建的联盟模式。通过构建涵盖政府补贴、建设成本与…...

【前端样式】用 aspect-ratio 实现等比容器:视频封面与图片占位的终极解决方案

在网页开发中&#xff0c;处理视频封面、图片卡片等需要固定比例的容器一直是前端工程师的必修课。本文将以 aspect-ratio 属性为核心&#xff0c;深入探讨如何优雅实现等比容器&#xff0c;并通过完整代码示例和常见问题解析&#xff0c;助你彻底掌握这一现代布局利器。 目录…...

redis常用的五种数据类型

redis常用的五种数据类型 文档 redis单机安装redis数据类型-位图bitmap 说明 官网操作命令指南页面&#xff1a;https://redis.io/docs/latest/commands/?nameget&groupstring 常用命令 keys *&#xff1a;查看所有键exists k1 k2&#xff1a;键存在个数type k1&…...

Cribl 利用表向event 中插入相应的字段-example-02

Working with Lookups – Example 2 ​ Let’s assume we have the following lookup file, and given both the fields impact and priority in an event, we would like to add a corresponding ingestion-time field called severity. cisco_sourcefire_severity.csv im…...

SystemWeaver详解:从入门到精通的深度实战指南

SystemWeaver详解&#xff1a;从入门到精通的深度实战指南 文章目录 SystemWeaver详解&#xff1a;从入门到精通的深度实战指南一、SystemWeaver环境搭建与基础配置1.1 多平台安装全流程 二、新手必学的十大核心操作2.1 项目创建全流程2.2 建模工具箱深度解析 三、需求工程与系…...

归一化对C4.5决策树无效的数学原理与实证分析

一、引言 在机器学习的预处理流程中&#xff0c;归一化&#xff08;Normalization&#xff09;常被视作提升模型性能的"银弹"。然而&#xff0c;这一经验法则在决策树算法中却遭遇挑战——尤其对基于信息增益比的C4.5算法&#xff0c;归一化操作几乎不产生任何效果。…...

# 05_Elastic Stack 从入门到实践(五)

05_Elastic Stack 从入门到实践(五) 一、Elasticsearch集群之分布式文档(文档的写操作、搜索操作) 1、文档的写操作 1)新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。 2)下面我们罗列在主分片和复制分片上成功新建、…...

n8n 中文系列教程_05.如何在本机部署/安装 n8n(详细图文教程)

n8n 是一款强大的开源工作流自动化工具&#xff0c;可帮助你连接各类应用与服务&#xff0c;实现自动化任务。如果你想快速体验 n8n 的功能&#xff0c;本机部署是最简单的方式。本教程将手把手指导你在 Windows 或 MacOS 上通过 Docker 轻松安装和运行 n8n&#xff0c;无需服务…...

Spark,从0开始配置Spark的local模式

1.启动虚拟机 2.通过finalshell连接虚拟机&#xff0c;并上传安装文件到 /opt/software下 3.解压spark安装文件到/opt/module下 tar -zxvf spark-3.3.1-bin-hadoop3.tgz -C /opt/module/ 4.重命名&#xff0c;把解压后的文件夹改成spark-local。因为后续我们还会使用其他的配置…...

策略模式:优雅应对多变的业务需求

一、策略模式基础概念 策略模式&#xff08;Strategy Pattern&#xff09; 是一种行为型设计模式&#xff0c;它通过定义一系列可互换的算法族&#xff0c;并将每个算法封装成独立的策略类&#xff0c;使得算法可以独立于使用它的客户端变化。策略模式的核心思想是 “将算法的…...

性能比拼: Nginx vs Apache

本内容是对知名性能评测博主 Anton Putra Nginx vs Apache Performance 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 引言 在本视频中&#xff0c;我们将比较 Nginx 与 Apache 这两个 Web 服务器。我们将进行多项测试&#xff0c;并且实际上&#xff0c;在某些情…...

(7)NodeJS的使用与NPM包管理器

本系列教程目录&#xff1a;Vue3Element Plus全套学习笔记-目录大纲 文章目录 第1章 NodeJS1.1 NodeJS简介1.2 NodeJS下载1.3 Node基础入门1.3.1 控制台输出1.3.2 使用函数 1.4 NodeJS模块化编程1.5 NodeJS内置模块1.5.1 fs模块1.5.2 http模块 1.6 NPM包管理工具1.6.1 修改npm镜…...

策略模式:思考与解读

原文地址:策略模式&#xff1a;思考与解读 更多内容请关注&#xff1a;7.深入思考与解读设计模式 引言 你是否曾遇到过这样的情况&#xff1a;在一个系统中&#xff0c;有许多算法或策略&#xff0c;每种策略的实现逻辑相似&#xff0c;但在某些情况下需要进行替换和扩展&am…...

1.Vue3 - 创建Vue3工程

目录 一、 基于vue-cli 脚手架二、基于vite 推荐2.1 介绍2.2 创建项目2.3 文件介绍2.3.1 extensions.json2.3.2 脚手架的根目录2.3.3 主要文件 src2.3.3.1 main.js2.3.3.2 App.vue 组件2.3.3.3 conponents 2.3.4 env.d.ts2.3.5 index.html 入口文件2.3.6 package2.3.7 tsconfig…...

Spring MVC 执行流程全解析:从请求到响应的七步走

Spring MVC 的工作流程&#xff0c;漏了这一个今天刚好面试提到了&#xff0c;没回答出来&#xff0c;记录一下。 &#x1f9ed; Spring MVC 整体执行流程一览&#xff08;从请求到响应&#xff09; ✅ 1. 请求发出&#xff1a;浏览器发送 HTTP 请求 如用户访问&#xff1a; …...

四元数转旋转矩阵

目录 gsplat 四元数转旋转矩阵等同代码实现 scipy 四元数转旋转矩阵替换代码 gsplat 四元数转旋转矩阵等同代码实现 import torch import torch.nn.functional as Fdef quat_act(x: torch.Tensor) -> torch.Tensor:return x / x.norm(dim-1, keepdimTrue)def normalized_q…...

Pytorch的极简transformer用于时间序列预测

本博客来源于CSDN机器鱼&#xff0c;未同意任何人转载。 更多内容&#xff0c;欢迎点击本专栏&#xff0c;查看更多内容。 目录 0.引言 1.数据准备 2. 网络搭建 3. 完整代码 4. 结语 0.引言 在【博客】中&#xff0c;我们基于tensorflow2.x深度学习框架搭建了transforme…...

垂直行业突围:工业软件在汽车、航空领域的 “破壁” 实践

在当今科技高速发展的时代&#xff0c;工业软件已悄然完成从通用工具到垂直行业 “战略武器” 的蜕变。特别是在汽车与航空这两大高端制造领域&#xff0c;工业软件的价值早已超越单纯的效率提升&#xff0c;成为关乎核心技术自主可控的关键要素&#xff0c;一场围绕工业软件的…...

人工智能在智能家居中的应用与发展

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;智能家居逐渐成为现代生活的重要组成部分。从智能语音助手到智能家电&#xff0c;AI正在改变我们与家居环境的互动方式&#xff0c;让生活更加便捷、舒适和高效。本文将探讨人工智能在智能家居中的应用现状、…...

维度建模工具箱 提纲与总结

这里写自定义目录标题 基本概念事实表和维度表BI(Business Intelligence) 产品 事实表事实表的粒度事实表的种类 维度表建模技术基本原则避免用自然键作为维度表的主键&#xff0c;而要使用类似自增的整数键避免过度规范化避免变成形同事实表的维度表 SCD(Slowly Changed Dimen…...

Vue3 源码解析(六):响应式原理与 reactive

今天这篇文章是笔者会带着大家一起深入剖析 Vue3 的响应式原理实现&#xff0c;以及在响应式基础 API 中的 reactive 是如何实现的。对于 Vue 框架来说&#xff0c;其非侵入的响应式系统是最独特的特性之一了&#xff0c;所以不论任何一个版本的 Vue&#xff0c;在熟悉其基础用…...

规则引擎 - Easy Rules

Easy Rules 依赖demodemo1demo2 总结 Easy Rules 是一个轻量级的 Java 规则引擎&#xff0c;使用简单&#xff0c;适合快速开发和简单的规则场景&#xff0c;适合对于一些判断&#xff0c;是否属于白名单&#xff0c;是否有特殊权限&#xff0c;是否属于当前区域&#xff0c;调…...

uniapp打ios包

uniapp在windows电脑下申请证书并打包上架 前言 该开发笔记记录了在window系统下&#xff0c;在苹果开发者网站生成不同证书&#xff0c;进行uniapp打包调试和上线发布&#xff0c;对window用户友好 注&#xff1a;苹果打包涉及到两种证书&#xff1a;开发证书 和 分发证书 …...

from tensorflow.keras.models import Model中Model报红;以及动态链接库(DLL)初始化例程失败

博主也是网上搜索资料又问的kimi 试了一节课 总结下来&#xff1a; 1、用这句话导入Model from tensorflow.keras.models import Model 2、更新pip pip install --upgrade pip 3、卸载重装tensorflow pip uninstall tensorflow 4、使用阿里云使tensorflow降低到2.8.0&a…...

【初阶数据结构】树——二叉树(上)

文章目录 目录 前言 一、树 1.树的概念与结构 2.树相关术语 3.树的表示 二、二叉树 1.概念与结构 2.特殊的二叉树 3.二叉树存储结构 总结 前言 本篇带大家学习一种非线性数据结构——树&#xff0c;简单认识树和二叉数以及了解二叉树的存储结构。 一、树 1.树的概念与结构 树…...

Debian GNU/Linux的新手入门介绍

Debian GNU/Linux&#xff1a;起源、基本介绍与发行版对比 一、起源与发展历程 Debian GNU/Linux 是现存最古老的 Linux 发行版之一&#xff0c;由 Ian Murdock 于 1993 年 8 月 16 日创立。其名称结合了他的女友&#xff08;后成为妻子&#xff09;Debra 和他自己的名字 Ian…...

13 数据存储单位与 C 语言整数类型:从位到艾字节、常见整数类型及其范围、字面量后缀、精确宽度类型详解

1 数据存储单位 在计算机科学领域&#xff0c;数据存储采用分层级的单位体系&#xff0c;各层级单位以 2 的幂次方为换算基础&#xff0c;而非传统数学中的 10 的幂次方。 以下是常见的数据存储单位介绍&#xff1a; 位&#xff08;bit&#xff0c;b&#xff09;是计算机中的最…...