软件编程
位置:首页>> 软件编程>> java编程>> SpringBoot动态修改yml配置文件的方法详解

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

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

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

前言

记录下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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com