配置文件热加载

目前只支持单个文件

Posted by xujie on December 3, 2018

正所谓前人栽树,后人乘凉。 感谢Huxpro提供的博客模板,同时也感谢BY前辈……

我的的博客

前言

在开发项目中,有时候需要我们将一些可配置的参数做成一个配置文件或者多个,但是在使用过程可能会出现这种情况:项目正在运行,但是又需要改配置文件。而且配置文件修改后还要重启服务才能生效。这样的操作就有点不太理想化,当项目有一定的用户量时,这种操作也肯定会影响到实际使用体验。那么重点来了,这篇文章就是为了解决这个问题才诞生的。

写这个教程的时候我也是查询了相关的文档,发现其实有框架可以解决这个问题,比如百度的disconf和spring cloud config,但是这两个框架是解决分布式架构的。由于项目还没有使用分布式的结构,如果使用这些框架就未免大材小用了。

解决思路:

  • 配置文件项目外部(这么做也是为了兼容springboot项目,避免修改配置文件还需要重新打包上传)
  • 定时读取配置文件
  • 读取的数据放入内存

忘了说了,我这里使用框架是springboot

详细教程:

1.新建配置文件,将配置文件放置到指定盘符(我这里放到D:/configData文件夹下,window服务器可以指定盘符,luinx系统我一般放置到/opt/configData文件夹下)

2.新建GlobalVariable的class文件,读取的配置文件内容都会放到这个map集合中,只要服务器不重启,一直会存在内存中,但是要注意,haspmap的容量是2的30次方,如果超过这个容量,可能会失效

    public class GlobalVariable {
        private static Map<String, Object> shoolinfoSet = new HashMap<>();
        public static  Map<String, Object> getShoolinfoSet() {
            return shoolinfoSet;
        }
        public static void setShoolinfo(Map<String, Object> map) {
                GlobalVariable.shoolinfoSet = map;
        }
    }

3.创建配置文件读取工具ConfigUtil

    public class ConfigUtil {
        private static InputStream ins = null;
        private static Properties p = null;
        private static Map<String, Object>  map = GlobalVariable.getShoolinfoSet();
        static {
            try {
                File file = ResourceUtils.getFile(AutoLoadUtils.checkOSType());
                ins = new BufferedInputStream(new FileInputStream(file));
                p = new Properties();
                p.load(ins);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (ins != null) {
                    try {
                        ins.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
            
            
        /**
        * 根据key查询value,返回string类型的数据
        * @param key
        * @return
        */
        public static String getConfig(String key){
            if (!map.containsKey(key)){
                map.put(key, p.getProperty(key));
            }
            return (String) map.get(key);
        }
    }

4. 定时任务类

    //定时读取配置文件
    @Configuration
    @EnableScheduling
    public class AutoLoadUtils {
        private final static String WINDOWS_MEMCACHED_LOG = "D:\\configData\\schoolInfo.properties";
        private final static String LINUX_MEMCACHED_LOG = "/opt/configData/schoolInfo.properties";

        private static InputStream ins = null;
        private static Properties p = null;
        private Logger log = LoggerFactory.getLogger(this.getClass());
        private static Map<String, Object>  map = GlobalVariable.getShoolinfoSet();

        /**
        * @description 自动加载学校信息(每隔5分钟扫描一次,获取最新的数据)
        * @version V1.0.0
        * @motto 昨夜西风凋碧树。独上高楼,望尽天涯路
        * @methodName AutoLoadSchoolInfo
        * @author Gypsophila
        * @date 2018/11/26
        * @param
        * @return
        */
        @Scheduled(cron="*/5 * * * * ?")
        public void AutoLoadSchoolInfo(){
            try {
                File file = ResourceUtils.getFile(checkOSType());
                ins = new BufferedInputStream(new FileInputStream(file));
                p = new Properties();
                log.debug("[自动加载学校信息]时间:{},加载数据:{}",new Date().getTime(),p);
                p.load(ins);
                for (Enumeration e = p.propertyNames(); e.hasMoreElements(); ) {
                    String key = (String)e.nextElement();
                    map.put(key, p.getProperty(key));
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (ins != null) {
                    try {
                        ins.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
            
        /**
        * @description 检查服务器类型
        * @version V1.0.0
        * @motto 昨夜西风凋碧树。独上高楼,望尽天涯路
        * @methodName checkOSType
        * @author Gypsophila
        * @date 2018/11/26
        * @param
        * @return
        */
        public static String checkOSType(){
            Properties properties = System.getProperties();
            String property = properties.getProperty("os.name");
            if (property.contains("Windows")){
                return WINDOWS_MEMCACHED_LOG;
            }
            return LINUX_MEMCACHED_LOG;
        }
    }