springboot系列之免重启动态修改配置

前言:实际项目开发中,经常得通过修改配置来改变业务线或者调试,对于修改代码重新打包部署,真心麻烦,所以这里找到一种不重启服务,直接修改配置文件内容,就可以生效的方式。

正文

1.话不多说,上依赖,该依赖是针对yml配置文件的操作,不要使用properties


      org.yaml
      snakeyaml
      1.25

2.上配置文件,分为总的和分支

application.yml

server:
  port: 9888

spring:
  profiles:
    active: tst

application-tst.yml

##配置变量
myTestConf: world
myTestConf2: hello

3.增加一个配置文件工具类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;

/**
 * 动态操作yml配置文件工具类
 * 【需要将config配置文件夹和项目jar包放在同级别目录下,这样修改config下的配置文件后,jvm才能及时得获取新的配置】
 */
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 = null;
        System.out.println("The config file "+path+"/config/"+fileName+" is exist? "+file.exists());
        if (file.exists()) {
            in = new FileInputStream(path+"/config/" + fileName);
        } else {
            //如果没有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;
            }
        }
        throw new RuntimeException("不可能到这里的...");
    }

}

4.增加一个配置实体类ConfValEntity.java

/**
 * 配置文件实体类,供内存中使用(类中变量都是配置变量)
 */
public class ConfValEntity {
    public static String myTestConf;
    public static String myTestConf2;
}

5.增加一个自启动类Initialization.java,进行配置内容的定时更新

import com.wong.gogo.common.YmlUtil;
import com.wong.gogo.model.ConfValEntity;
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;

/**
 * spring容器初始化完成后进行一些其他初始化操作
 */
@Slf4j
@Component
public class Initialization implements ApplicationRunner {

    private static ScheduledExecutorService exec = 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异常");
        }

        //开启定时刷新内存中配置文件内容
        log.info("refresh config file start");
        exec.scheduleAtFixedRate(Initialization::updateConfVal, 0, 10, TimeUnit.SECONDS);
        log.info("refresh config file end");
    }

    /**
     * 更新配置文件值
     */
    private static void updateConfVal(){
        try{
            Map lhm= YmlUtil.loadYaml("application-"+profile+".yml");
            log.info("profile="+"application-"+profile+".yml");

            String myTestConf = (String) YmlUtil.getValByKey(lhm,"myTestConf");
            ConfValEntity.myTestConf = myTestConf;
            String myTestConf2 = (String) YmlUtil.getValByKey(lhm,"myTestConf2");
            ConfValEntity.myTestConf2 = myTestConf2;
            log.info("实时配置myTestConf=="+myTestConf+",myTestConf2=="+myTestConf2);

        } catch (Exception e){
            log.error("更新配置文件值异常: ", e);
        }
    }
}

6.最后打成jar包,在jar包的同级目录下新建config文件夹,然后将配置文件放入config文件夹,完成!

7.启动jar包服务,运行期间如果修改配置文件内容,则内存中的变量值就会相应的改变。

你可能感兴趣的:(springboot,动态修改配置,yml配置更改,免重启)