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

高级开发 | 零人工干预的 @Value 实时刷新

高级开发 | 零人工干预的 @Value 实时刷新

目标:运行时把 最新配置 写进 Environment自动广播事件所有带 @Value 的 Bean 毫秒级重注入,零人工干预


1. 整体思路

  1. 动态 PropertySource 始终指向最新配置。
  2. Spring 事件总线 在配置变更时自动触发。
  3. 统一重注入器 监听事件,批量刷新所有 @Value 字段。

2. 代码实现(可直接拷贝)

2.1 动态 PropertySource(实时数据源)

@Component
public final class DynamicPropertyHolder extends PropertySource<Object> {private final AtomicReference<Map<String, Object>> store = new AtomicReference<>(Map.of());public DynamicPropertyHolder() {super("dynamic");}@Overridepublic Object getProperty(String name) {return store.get().get(name);}/** 发布配置变更事件 */public void publish(Map<String, Object> newMap) {Map<String, Object> old = store.getAndSet(newMap);if (!Objects.equals(old, newMap)) {SpringUtil.publishEvent(new ConfigRefreshedEvent());}}
}

2.2 自动注册到 Environment(最高优先级)

@Component
public class DynamicPropertyRegistrar implements EnvironmentAware {private ConfigurableEnvironment env;@Overridepublic void setEnvironment(Environment environment) {this.env = (ConfigurableEnvironment) environment;env.getPropertySources().addFirst(SpringUtil.getBean(DynamicPropertyHolder.class));}
}

2.3 统一重注入器(监听事件,自动刷新)

@Component
public class ValueAutoRefresher implements ApplicationListener<ConfigRefreshedEvent> {private final ConfigurableListableBeanFactory factory;public ValueAutoRefresher(ConfigurableListableBeanFactory factory) {this.factory = factory;}@Overridepublic void onApplicationEvent(ConfigRefreshedEvent event) {String[] names = factory.getBeanDefinitionNames();for (String name : names) {Object bean = factory.getBean(name);ReflectionUtils.doWithFields(bean.getClass(), field -> {if (field.isAnnotationPresent(Value.class)) {field.setAccessible(true);String spel = field.getAnnotation(Value.class).value();String key  = spel.replaceAll("\\$\\{([^:]+?)(:.*)?}", "$1");Object val  = factory.resolveEmbeddedValue("${" + key + "}");ReflectionUtils.setField(field, bean, val);}});}}
}

3. 触发方式(零人工)

任何线程只要把最新配置塞进 DynamicPropertyHolder 即可:

@Autowired DynamicPropertyHolder holder;public void updateConfig() {holder.publish(Map.of("sms.apiKey", "newKey123","sms.timeout", 3000));
}
  • holder.publish(…) 自动写 Environment
  • ConfigRefreshedEvent 自动广播
  • ValueAutoRefresher 自动重注入所有 @Value

4. 避坑 & 性能

说明
构造器注入不支持刷新,改用字段/Setter
并发安全AtomicReference + 事件总线无锁
刷新粒度只扫描带 @Value 的 Bean,O(N) ≈ 毫秒级

5. 一句话总结

最新配置 → DynamicPropertyHolder → 事件总线 → 自动刷新所有 @Value
全程 零人工干预,Spring 原生能力即可实现 毫秒级热更新

http://www.dtcms.com/a/313241.html

相关文章:

  • 直流无刷电机(一)
  • ElementUI之使用以及表单验证
  • lumerical——锥形波导偏振转换
  • 第九章:了解特殊场景下的redis
  • 解决dify前端页面中公式显示的问题
  • 字典序最小的拼接字符串(贪心+全排列)详解
  • 数据分析—numpy库
  • Pytorch-03数据的Transform
  • 2106. 摘水果,梳理思路
  • 新手向:Python制作贪吃蛇游戏(Pygame)
  • Redis面试精讲 Day 9:Redis模块开发与扩展
  • 信创数据库-DM(达梦)数据库安装教程
  • Rust:如何访问 *.ini 配置文件?
  • 【项目日志|苍穹外卖】 Day1:项目环境搭建与架构设计
  • 反向代理+网关部署架构
  • Java学习第一百零二部分——API网关
  • Claude Code入门学习笔记(五)--Claude Code命令行输入
  • 大白话讲解MCP
  • 多种单文件版分析型数据库调用底层函数对比
  • [Oracle] TO_DATE()函数
  • cs285 lecture13
  • 手机端使用表格填写表单问题
  • 复现YOLOV5+训练指定数据集
  • STM32-ESP8266通过MQTT与阿里云通讯
  • MySQL连接算法和小表驱动大表的原理
  • 李宏毅深度学习教程 第8-9章 生成模型+扩散模型
  • 【Django】-7- 实现注册功能
  • 09.Redis 常用命令
  • Android 之 蓝牙通信(2.0 经典)
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-58,(知识点:硬件产品的功率优化)