在我们的生产系统上,如果我们修改了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。给自己和家人一个保障。