SpringBoot支持动态更新配置文件参数

稿定智能设计202501242152

前言

博主介绍:✌目前全网粉丝3W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。

涵盖技术内容:Java后端、大数据、算法、分布式微服务、中间件、前端、运维等。

博主所有博客文件目录索引:博客目录索引(持续更新)

视频平台:b站-Coder长路

章节描述

在springboot服务启动之后,想要通过接口来动态修改配置文件参数,实现动态参数配置信息获取。

gitee:https://gitee.com/changluJava/demo-exer/tree/master/SpringBoot/springboot-config/src/main/java/com/changlu/springbootconfig

github:https://github.com/changluya/Java-Demos/tree/master/SpringBoot/springboot-config/src/main/java/com/changlu/springbootconfig

实现接口动态刷新配置参数

image-20250123232945851

代码实现

1、DynamicPropertyUpdater(动态配置项更新器)

自定义DynamicPropertySource动态配置类,接着本质通过environment.getPropertySources()来获取到配置项属性器,后续更新配置项去构造DynamicPropertySource添加到属性器即可完成属性配置覆盖。

package com.changlu.springbootconfig.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class DynamicPropertyUpdater {

   private static final Logger logger = LoggerFactory.getLogger(DynamicPropertyUpdater.class);

   private final ConfigurableEnvironment environment;

   public DynamicPropertyUpdater(ConfigurableEnvironment environment) {
       this.environment = environment;
   }

   /**
    * 动态更新 Environment 中的配置项值
    *
    * @param key   配置项的键
    * @param value 配置项的新值
    */
   public void updateProperty(String key, String value) {
       logger.info("Updating property: {} = {}", key, value);
       MutablePropertySources propertySources = environment.getPropertySources();
       // 添加或更新属性
       propertySources.addFirst(new DynamicPropertySource(key, value));
   }

   /**
    * 批量动态更新 Environment 中的配置项值
    * @param properties 配置项
    */
   public void updateProperties(Map<String, String> properties) {
       for (Map.Entry<String, String> entry : properties.entrySet()) {
           // 复用单独更新配置项逻辑
           this.updateProperty(entry.getKey(), entry.getValue());
       }
   }

   /**
    * 自定义动态属性源
    */
   private static class DynamicPropertySource extends PropertySource<String> {

       private final String key;
       private final String value;

       public DynamicPropertySource(String key, String value) {
           super("dynamicPropertySource"); // 属性源的名称
           this.key = key;
           this.value = value;
       }

       @Override
       public Object getProperty(String name) {
           // 如果传入的 key 匹配,则返回对应的 value
           if (key.equals(name)) {
               return value;
           }
           return null; // 如果不匹配,返回 null
       }
   }
}

2、EnvironmentContext(environment管理器)

package com.changlu.springbootconfig.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class EnvironmentContext {

    @Autowired
    private Environment environment;

    public String getProperty(String key, String defaultVal) {
        return environment.getProperty(key, defaultVal);
    }
}

3、ConfigController 实现查询配置、更新配置接口

image-20250123233747874

import com.changlu.springbootconfig.config.DynamicPropertyUpdater;
import com.changlu.springbootconfig.config.EnvironmentContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/config")
public class ConfigController {

    @Autowired
    private DynamicPropertyUpdater dynamicPropertyUpdater;

    @Autowired
    private EnvironmentContext environmentContext;

    /**
     * 动态更新配置项的值
     *
     * @param key   配置项的键
     * @param value 配置项的新值
     * @return 更新结果
     */
    @PostMapping("/update")
    public String updateConfig(@RequestParam String key, @RequestParam String value) {
        dynamicPropertyUpdater.updateProperty(key, value);
        return "Config updated successfully: " + key + " = " + value;
    }

    /**
     * 根据 key 获取配置项的值
     *
     * @param key 配置项的键
     * @return 配置项的值
     */
    @GetMapping("/get")
    public String getConfig(@RequestParam String key) {
        String value = environmentContext.getProperty(key, "未找到对应的配置项");
        return key + " = " + value;
    }

}

测试

首先在application.properties配置文件中补充一个参数配置:

server.port=8080
changlu.param=parm1

1)启动服务后,查询下参数信息:changlu.param

image-20250123234012131

正常获取到结果值parm1。

2)接着我们调用update更新参数接口

更新changlu.param参数值为:789

image-20250123234204115

3)此时我们再次查询下该参数:

image-20250123234257625

当前已经得到了最新的参数值为:789


实现刷新当前使用的配置文件

目的

在真实场景下,我们会直接上到服务器上修改配置文件参数,接着想要通过调用接口重新加载该配置文件中的所有参数配置信息。

动作:修改配置文件参数项。

发起:调用/refresh接口实现动态刷新。

代码实现

1、SystemPropertyUtil (实现自定义conf配置路径user.dir.conf )

实际场景中,我们的配置文件不会直接打包在jar包中,通常会指定一个配置文件路径。

image-20250123234911039

SystemPropertyUtil:

import java.io.File;

public class SystemPropertyUtil {

    public static void setSystemUserDir() {
        String dir = System.getProperty("user.dir");
        String conf = String.format("%s/%s", dir, "conf");
        File file = new File(conf);
        if(!file.exists()) {
            dir = dir.substring(0, dir.lastIndexOf("/"));
            conf = String.format("%s/%s", dir, "conf");
            file = new File(conf);
            if(file.exists()) {
                System.setProperty("user.dir", dir);
            }
        }
        System.setProperty("user.dir.conf", System.getProperty("user.dir") + "/conf");
    }
}

接着在启动器服务运行前调用方法来设置全局变量参数user.dir.conf:

image-20250123235050109

SystemPropertyUtil.setSystemUserDir();

此时我们的配置文件在当前工程目录下的conf中:

image-20250123235200056

配置参数值如下:

server.port=8756
changlu.test=444

2、ConfigFileReloader(实现配置文件加载器)

image-20250123235332797

在加载器中,实现了一个方法会去读取user.dir.conf这个变量路径值,此时得到的是/conf的全路径,接着我们去补充配置文件名application.properties即可:

ConfigFileReloader.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.stereotype.Component;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

@Component
public class ConfigFileReloader {

    private final ConfigurableEnvironment environment;

    @Autowired
    public ConfigFileReloader(ConfigurableEnvironment environment) {
        this.environment = environment;
    }

    /**
     * 重新加载配置文件
     *
     * @throws IOException 如果文件读取失败
     */
    public void reloadConfig() throws IOException {
        Properties properties = new Properties();
        try (FileInputStream fis = new FileInputStream(System.getProperty("user.dir.conf") + "/application.properties")) {
            properties.load(fis);
        }

        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addFirst(new PropertiesPropertySource("dynamicConfig", properties));
    }
}

3、EnvironmentContext 指定默认读取配置文件路径参数

image-20250123235826147

补充属性源读取路径信息:PropertySource注解中读取静态变量对应conf路径下application.properties

@Component
@PropertySource(value = "file:${user.dir.conf}/application.properties")
public class EnvironmentContext {

4、实现刷新配置文件参数接口

image-20250123235535739

@Autowired
private ConfigFileReloader configFileReloader;

/**
 * 刷新配置文件
 *
 * @return 配置项的值
 */
@GetMapping("/refresh")
public String refreshConfig() throws IOException {
    configFileReloader.reloadConfig();
    return "success";
}

后续步骤就是,我们修改conf下的配置文件参数值,然后调用下生效参数接口即可刷新当前应用服务的配置信息。


测试

确认好配置信息:

image-20250123235656206

接着我们启动服务,来调用下获取参数配置信息接口:正常读取到parm1

image-20250123235939279

接着我们手动将配置文件参数修改:

image-20250124000001117

接着调用刷新配置文件接口:

image-20250124000035839

成功刷新,此时我们再去读取下该配置信息:

image-20250124000109778

当前读取到的配置参数为parm2,刷新文件配置项生效!


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

题海拾贝:P2085 最小函数值

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

企业微信SCRM开创客户管理新纪元推动私域流量高效转化

内容概要 在当今瞬息万变的数字化时代&#xff0c;企业面临着前所未有的客户管理挑战。消费者的需求日益多样化&#xff0c;他们希望能够随时随地与品牌沟通。因此&#xff0c;越来越多的企业意识到&#xff0c;传统的客户管理方式已无法满足市场的需求。在这样的背景下&#…

电子应用设计方案104:智能家庭AI弹簧床系统设计

智能家庭 AI 弹簧床系统设计 一、引言 智能家庭 AI 弹簧床系统旨在为用户提供更加舒适、个性化的睡眠体验&#xff0c;通过结合人工智能技术和先进的床垫设计&#xff0c;实时监测和调整睡眠环境&#xff0c;以满足不同用户的需求。 二、系统概述 1. 系统目标 - 自动适应用户…

【25考研】人大计算机考研复试该怎么准备?有哪些注意事项?

人大毕竟是老牌985&#xff0c;复试难度不会太低&#xff01;建议同学认真复习&#xff01;没有机试还是轻松一些的&#xff01; 一、复试内容 由公告可见&#xff0c;复试包含笔试及面试&#xff0c;没有机试&#xff01; 二、参考书目 官方无给出参考书目&#xff0c;可参照…

随着监测技术的不断升级,将为智能决策提供强大的数据支持和智能帮助的智慧能源开源了

简介 AI视频监控平台, 是一款功能强大且简单易用的实时算法视频监控系统。愿景在最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;减少企业级应用约 95%的开发成本&#xff0c;用户仅需在界面上…

vim如何设置自动缩进

:set autoindent 设置自动缩进 :set noautoindent 取消自动缩进 &#xff08;vim如何使设置自动缩进永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

字节跳动发布UI-TARS,超越GPT-4o和Claude,能接管电脑完成复杂任务

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

使用eNSP配置GRE VPN实验

实验拓扑 实验需求 1.按照图示配置IP地址 2.在R1和R3上配置默认路由使公网区域互通 3.在R1和R3上配置GRE VPN&#xff0c;使两端私网能够互相访问&#xff0c;Tunne1口IP地址如图 4.在R1和R3上配置RIPv2来传递两端私网路由 实验步骤 GRE VPN配置方法&#xff1a; 发送端&#x…

机器学习-线性回归(对于f(x;w)=w^Tx+b理解)

一、&#x1d453;(&#x1d499;;&#x1d498;) &#x1d498;T&#x1d499;的推导 学习线性回归&#xff0c;我们那先要对于线性回归的表达公示&#xff0c;有所认识。 我们先假设空间是一组参数化的线性函数&#xff1a; 其中权重向量&#x1d498; ∈ R&#x1d437; …

Swing使用MVC模型架构

什么是MVC模式? MVC是一组英文的缩写,其全名是Model-View-Controller,也就是“模型-视图-控制器”这三个部分组成。这三个部分任意一个部分发生变化都会引起另外两个发生变化。三者之间的关系示意图如下所示: MVC分为三个部分,所以在MVC模型中将按照此三部分分成三…

Windows 环境下 Docker Desktop + Kubernetes 部署项目指南

Windows 环境下 Docker Desktop Kubernetes 部署项目指南 一、环境准备二、安装与配置 Kubernetes安装 windows 版的 docker启动 kubernetes安装 windows 版的 kubectl 工具下载 k8s-for-docker-desktop启动 Kubernetes Dashboard 二、在 Kubernetes 上部署项目创建一个 demo …

redis实现lamp架构缓存

redis服务器环境下mysql实现lamp架构缓存 ip角色环境192.168.242.49缓存服务器Redis2.2.7192.168.242.50mysql服务器mysql192.168.242.51web端php ***默认已安装好redis&#xff0c;mysql 三台服务器时间同步&#xff08;非常重要&#xff09; # 下载ntpdate yum -y install…

【Excel】【VBA】Reaction超限点筛选与散点图可视化

【Excel】【VBA】Reaction超限点筛选与散点图可视化 功能概述 这段代码实现了以下功能&#xff1a; 从SAFE输出的结果worksheet通过datalink获取更新数据从指定工作表中读取数据检测超过阈值的数据点生成结果表格并添加格式化创建可视化散点图显示执行时间 流程图 #mermaid-…

Java导出通过Word模板导出docx文件并通过QQ邮箱发送

一、创建Word模板 {{company}}{{Date}}服务器运行情况报告一、服务器&#xff1a;总告警次数&#xff1a;{{ServerTotal}} 服务器IP:{{IPA}}&#xff0c;总共告警次数:{{ServerATotal}} 服务器IP:{{IPB}}&#xff0c;总共告警次数:{{ServerBTotal}} 服务器IP:{{IPC}}&#x…

智能化加速标准和协议的更新并推动验证IP(VIP)在芯片设计中的更广泛应用

作者&#xff1a;Karthik Gopal, SmartDV Technologies亚洲区总经理 智权半导体科技&#xff08;厦门&#xff09;有限公司总经理 随着AI技术向边缘和端侧设备广泛渗透&#xff0c;芯片设计师不仅需要考虑在其设计中引入加速器&#xff0c;也在考虑采用速度更快和带宽更高的总…

RabbitMQ5-死信队列

目录 死信的概念 死信的来源 死信实战 死信之TTl 死信之最大长度 死信之消息被拒 死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或直接到queue 里了&#xff0c;consumer 从 queue 取出消息进…

git常用命令学习

目录 文章目录 目录第一章 git简介1.Git 与SVN2.Git 工作区、暂存区和版本库 第二章 git常用命令学习1.ssh设置2.设置用户信息3.常用命令设置1.初始化本地仓库init2.克隆clone3.查看状态 git status4.添加add命令5.添加评论6.分支操作1.创建分支2.查看分支3.切换分支4.删除分支…

私有包上传maven私有仓库nexus-2.9.2

一、上传 二、获取相应文件 三、最后修改自己的pom文件

汽车定速巡航

配备定速巡航功能的车型&#xff0c;一般在方向盘附近设有4~6个按键&#xff08;可能共用键位&#xff09;。 要设置定速巡航&#xff0c;不仅需要方向盘上的按键&#xff0c;还要油门配合。 设置的一般流程&#xff1a; 开关&#xff1a;类似步枪上的“保险”&#xff0c;按…

安宝特方案 | AR在供应链管理中的应用:提升效率与透明度

随着全球化的不断深入和市场需求的快速变化&#xff0c;企业对供应链管理的要求也日益提高。如何在复杂的供应链环境中提升效率、降低成本&#xff0c;并确保信息的透明度&#xff0c;成为了各大行业亟待解决的问题。而增强现实&#xff08;AR&#xff09;技术&#xff0c;特别…