web应用生产环境properties文件自动更新

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

猜你喜欢

转载自aa860326.iteye.com/blog/2343253