SpringBoot动态修改yml配置文件的方法详解

作者:Maggieq8324 时间:2023-06-20 16:14:34 

前言

记录下SpringBoot修改yml配置文件后无需重启服务的方式(打包后生效),效果如下:

SpringBoot动态修改yml配置文件的方法详解

具体实现

实现代码

pom.xml

<dependencies>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
   </dependency>
</dependencies>

application.yml

#端口号
server:
 port: 31091
spring:
 profiles:
   active: dev

application-dev.yml

coisini:
   mail: maggieq8324@gmail.com

InitializationConfig.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @Description spring容器初始化完成后进行一些其他初始化操作
* @date Mar 24, 2022
* @version 1.0
*/
@Slf4j
@Component
public class InitializationConfig implements ApplicationRunner {
   private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
   private static String profile;
   @Override
   public void run(ApplicationArguments applicationArguments) throws Exception {
       scheduleUpdateConf();
   }
   private void scheduleUpdateConf() {
       try {
           Map lhm = YmlUtil.loadYaml("application.yml");
           profile = (String) YmlUtil.getValByKey(lhm, "spring.profiles.active");
       } catch (Exception e) {
           log.error("加载配置文件application.yml异常");
       }
       // TODO 开启定时刷新内存中配置文件内容
       log.info("refresh config file start");
       executorService.scheduleAtFixedRate(InitializationConfig::updateConfVal, 0, 10, TimeUnit.SECONDS);
       log.info("refresh config file end");
   }
   /**
    * 更新配置文件值
    */
   private static void updateConfVal(){
       try{
           Map lhm = YmlUtil.loadYaml("application-" + profile + ".yml");
           String mail = YmlUtil.getValByKey(lhm,"coisini.mail").toString();
           DynamicMailConfig instance = DynamicMailConfig.getInstance();
           if (!instance.getDynamicMail().equals(mail)) {
               instance.setDynamicMail(mail);
               log.info("实时配置mail更新:" + instance.getDynamicMail());
           }
       } catch (Exception e){
           log.error("更新配置文件值异常: ", e);
       }
   }
}

DynamicMailConfig.java

/**
* @Description 动态邮箱单例
* @date Mar 24, 2022
* @version 1.0
*/
public class DynamicMailConfig {
   private static String mail;
   private final static DynamicMailConfig dynamic;
   static {
       dynamic = new DynamicMailConfig();
   }
   private DynamicMailConfig() {
       mail = "";
   }
   public static DynamicMailConfig getInstance() {
       return dynamic;
   }
   public String getDynamicMail() {
       return mail;
   }
   public void setDynamicMail(String mail) {
       this.mail = mail;
   }
}

YmlUtil.java

import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @Description 动态操作yml配置文件工具类
*  【需要将config配置文件夹和项目jar包放在同级别目录下,这样修改config下的配置文件后,jvm才能及时得获取新的配置】
* @date Mar 24, 2022
* @version 1.0
*/
public class YmlUtil {
   public static LinkedHashMap loadYaml(String fileName) throws Exception{
       String path = System.getProperty("user.dir");
       File file = new File(path + "/config/" + fileName);
       InputStream in;
       if (file.exists()) {
           in = new FileInputStream(path + "/config/" + fileName);
       } else {
           // TODO 如果没有config文件夹,则从项目的resources目录下找
           in = YmlUtil.class.getClassLoader().getResourceAsStream(fileName);
       }
       LinkedHashMap lhm = new Yaml().loadAs(in, LinkedHashMap.class);
       return lhm;
   }
   public static Object getValByKey(Map lhm, String key) throws Exception{
       String[] keys = key.split("[.]");
       Map ymlInfo = lhm;
       for (int i = 0; i < keys.length; i++) {
           Object value = ymlInfo.get(keys[i]);
           if (i < keys.length - 1) {
               ymlInfo = (Map) value;
           } else if (value == null) {
               throw new Exception("key不存在");
           } else {
               return value;
           }
       }
       return null;
   }
}

测试 

TestController.java

@Slf4j
@RestController
public class TestController {
   @GetMapping("/getDynamicMail")
   public String getDynamicMail() {
       String dynamicMail = DynamicMailConfig.getInstance().getDynamicMail();
       log.info("getDynamicMail: " + dynamicMail);
       return dynamicMail;
   }
}

打包后配置文件放在与jar同级的config目录下

源码

GitHub:https://github.com/Maggieq8324/java-learn-demo/tree/master/springboot-dynamic-yml

Gitee:https://gitee.com/maggieq8324/java-learn-demo/tree/master/springboot-dynamic-yml

来源:https://blog.csdn.net/weixin_41182727/article/details/123798296

标签:SpringBoot,动态,修改,配置文件
0
投稿

猜你喜欢

  • C# 获取属性名的方法

    2023-03-05 07:02:18
  • mybatis in查询条件过长的解决方案

    2022-06-08 12:44:14
  • SimpleCommand实现图片下载(二)

    2023-05-21 00:25:17
  • 解析c#操作excel后关闭excel.exe的方法

    2021-08-14 16:55:22
  • SpringBoot选择自有bean优先加载实现方法

    2023-05-21 06:22:39
  • Android 动画之RotateAnimation应用详解

    2022-08-17 17:03:07
  • C#下使用XmlDocument操作XML详解

    2022-08-27 16:38:53
  • Android开发自定义双向SeekBar拖动条控件

    2022-06-02 03:55:25
  • Jmeter非GUI模式运行分布式测试

    2021-11-08 12:42:07
  • C# 实现绘制PDF嵌套表格案例详解

    2023-05-25 11:57:13
  • Android App后台服务报告工作状态实例

    2023-04-26 19:10:34
  • 快速学习C# 设计模式之职责链模式

    2022-03-28 17:47:45
  • Kotlin协程Job生命周期结构化并发详解

    2023-05-23 10:08:17
  • eclipse实现ElGamal数字签名

    2023-11-26 07:52:47
  • Android树形控件绘制方法

    2022-09-05 01:50:55
  • Java实现读取文章中重复出现的中文字符串

    2022-04-27 04:29:05
  • Spring中使用atomikos+druid实现经典分布式事务的方法

    2023-07-14 00:46:17
  • 宝塔面板配置及部署javaweb教程(全网最全)

    2023-11-10 15:26:27
  • Java如何使用HTTPclient访问url获得数据

    2023-11-12 04:16:21
  • maven实现jar包导入+导出方式

    2023-12-13 03:32:22
  • asp之家 软件编程 m.aspxhome.com