在我们的生产系统上,如果我们修改了properties中的一个配置项,如果想要这个配置生效,最简单的办法就是把这个应用重启。但是现实却不允许我们这样做。以下简单实现了一些代码,可以在修改配置项之后,做到自动加载这个配置的值。以下提供简单的思路和代码:
package com.busi.util; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; public class PropertyUtil { private static final Logger LOG = Logger.getLogger(PropertyUtil.class); private static final String PROPERTIES_SUFFIX = ".properties"; private static List<String> register = Collections.synchronizedList(new ArrayList<String>()); private static Map<String, String> keyValues = new ConcurrentHashMap<>(); private static Timer timer = new Timer(PropertyUtil.class.getName()); private static final long DELAY_TIME = 5000; // 延迟加载时间(单位:ms) private static String getClassPath(){ return PropertyUtil.class.getResource("/").getPath(); } private static String getFileAboslutePath(String filename){ StringBuffer buffer = new StringBuffer(); buffer.append(getClassPath()); buffer.append(filename); buffer.append(PROPERTIES_SUFFIX); return buffer.toString(); } public static void register(String... filenames){ for (String filename : filenames){ if (!register.contains(filename)){ register.add(filename); final TimerTask task = new PropertiesTask(filename); timer.schedule(task, 0, DELAY_TIME); } } } private static void loadProperties(String filename){ InputStream is = null; try { String fileAbsolutePath = getFileAboslutePath(filename); is = new FileInputStream(fileAbsolutePath); Properties properties = new Properties(); properties.load(is); is.close(); if (!properties.isEmpty()){ Set<Entry<Object, Object>> set = properties.entrySet(); Iterator<Map.Entry<Object, Object>> it = set.iterator(); String key = null; String value = null; while(it.hasNext()){ Entry<Object, Object> entry = it.next(); key = String.valueOf(entry.getKey()); value = String.valueOf(entry.getValue()); keyValues.put(key, value); } LOG.debug("#loadProperties() Properties文件内容:"+keyValues); } } catch (Exception e){ LOG.error("#loadProperties() Properties文件加载异常", e); } } public static String getStrValue(String key, String defaultValue){ String value = keyValues.get(key); return (null == value)?defaultValue:value.trim(); } public static Integer getIntValue(String key, Integer defaultValue){ String value = keyValues.get(key); return (null == value)?defaultValue:Integer.valueOf(value.trim()); } static class PropertiesTask extends TimerTask{ private String filename; private long lastModified; public PropertiesTask(String filename){ super(); this.filename = filename; this.lastModified = 0l; } public void run() { try { File file = new File(getFileAboslutePath(filename)); if (!file.exists()){ LOG.info(filename+"文件不存在!"); } long newLastModified = file.lastModified(); if (newLastModified > lastModified){ LOG.info("Properties文件["+filename+"]有变动,重新加载!"); lastModified = newLastModified; loadProperties(filename); } } catch (Exception e){ LOG.error("#run() Properties文件处理异常", e); } } } public static void main(String[] args) throws Exception{ PropertyUtil.register("system", "test"); Thread.sleep(200l); System.out.println(PropertyUtil.getStrValue("platform.name", "service")); } }
上诉代码还有一些不足的地方,欢迎拍砖。
--------------------------------------------------分割线--------------------------------------------------------
IT行业我认为是个高危的行业,“996”模式在互联网公司很常见,每每出现过劳死几乎是这个行当。因此我们应该具备一定风险意识,给自己投资一定的风险保证金:https://ssl.700du.cn/shopping/18611517897。给自己和家人一个保障。