目录

前言

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

SpringBoot - 动态修改yml配置文件_java



具体实现

实现代码

  • ​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​ ​目录下


源码


- End -

- 个人笔记 - - 仅供参考 -



以上为本篇文章的主要内容,希望大家多提意见,如果喜欢记得点个推荐哦

作者:​ ​Maggieq8324​