此处以数据源配置为例子,实际任何属性都可。

此方式,可解决修改配置文件,还要重新打包的问题

并且配置文件中的数据修改后,不需要重启服务器,也可获取最新修改后的配置信息。

步骤一:

启动类添加以下代码:

开启一个线程去定时刷新配置文件

 

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication implements ApplicationRunner
    {
    public static void main(String[] args) {
        // System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
        System.out.println("启动成功");
    }
    
    /**----------------------------------------------- 添加start ---------------------------------------------*/
    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) {
        System.out.println("加载配置文件application.yml异常");
        }
        // 开启定时刷新内存中配置文件内容
        System.out.println("refresh config file start");
        executorService.scheduleAtFixedRate(RuoYiApplication::updateConfVal, 0, 10, TimeUnit.SECONDS);
        System.out.println("refresh config file end");
    }
    
    /**
     * 更新配置文件值
     */
    private static void updateConfVal(){
        try{
            Map lhm = YmlUtil.loadYaml("application-" + profile + ".yml");
            String url = YmlUtil.getValByKey(lhm,"spring.datasource.druid.master.url").toString();
            String username = YmlUtil.getValByKey(lhm,"spring.datasource.druid.master.username").toString();
            String password = YmlUtil.getValByKey(lhm,"spring.datasource.druid.master.password").toString();
            DruidDynamicConfig instance = DruidDynamicConfig.getInstance();
            if (!instance.getDynamicUrl().equals(url)) {
                instance.setDynamicUrl(url);
            }
            if (!instance.getDynamicUsername().equals(username)) {
                instance.setDynamicUsername(username);
            }
            if (!instance.getDynamicPassword().equals(password)) {
                instance.setDynamicPassword(password);
            }
        } catch (Exception e){
            // System.out.println("更新配置文件值异常: ", e);
        }
    
    /**----------------------------------------------- 添加end ---------------------------------------------*/
    
}

步骤二:

修改属性的实例化,添加此实体类

/**
 * 动态数据源配置实体类
 */
public class DruidDynamicConfig {   
     private static String url;
    private static String username;
    private static String password;
    
    private final static DruidDynamicConfig dynamic;
    
    static {
        dynamic = new DruidDynamicConfig();
    }
    
    private DruidDynamicConfig() {
    url = "";
    username = "";
    password = "";
    }
    public static DruidDynamicConfig getInstance() {
        return dynamic;
    }
    public String getDynamicUrl() {
        return url;
    }
    public void setDynamicUrl(String url) {
        this.url = url;
    }
    public String getDynamicUsername() {
        return username;
    }
    public void setDynamicUsername(String username) {
        this.username = username;
    }
    public String getDynamicPassword() {
        return password;
    }
    public void setDynamicPassword(String password) {
        this.password = password;
    }
}

步骤三:

添加Yml工具类:YmlUtil.java

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;

/**
 *   @Description 动态操作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;
         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;
    }
}

步骤四:

将 application.yml 和 application-dev.yml 文件进行拷贝,放置到jar同目录下的config文件夹中(没有config创建即可)

 

 这样就完成了动态加载yml配置信息的工作了,只要yml文件有修改,就会动态去监听并加载。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐