1、 支持修改单个Properties文件时只重新加载修改的Properties文件
2、 Properties文件配置:时间限制,路径配置
类:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
@SuppressWarnings("unchecked")
public class PropertiesConfig {
private static final String propertiesSubPath="";//前面不要/最后要/
private static Map xmltable;
private static Map propMap = null;
private static final String configPath = StrUtil.getClassesPath()+"config/ir/PropertiesConfig.xml";
private static long lastModifyTime;
private static boolean initXML() {
boolean isReload = false;
File _file = new File(configPath);
long _lastModifyTime = _file.lastModified();
try {
// 如果是第一次加载或文件时间更改重新载入
if (xmltable == null || lastModifyTime != _lastModifyTime) {
isReload = true;
//System.out.println("======重新加载" + configPath);
Document document = StrUtil.readXML(configPath, "utf-8");
Element root = document.getRootElement();
List list = root.elements("property");
Iterator iterator = list.iterator();
xmltable = new Hashtable();
long now_time = Long
.parseLong(DateUtil.getTodayStr("yyyyMMdd"));//按格式读取日期字符串
while (iterator.hasNext()) {
try {
Element prop = (Element) iterator.next();
String file = prop.element("file").getTextTrim();
if (StringUtils.defaultIfEmpty(file, "").equals("")) {
continue;
}
String et = prop.element("endtime").getTextTrim();
if (et == null || et.trim().length()==0) {// 不填时间永不过期
} else {
long endtime = NumberUtils.toInt(et.replaceAll("-","").replaceAll(" ", ""));
if (endtime < now_time) {
continue;
}
}
PropConfigBean bean = new PropConfigBean();
String code = prop.element("code").getTextTrim();
Element pathe = prop.element("path");
String path = pathe.getTextTrim();
bean.setCode(code);
bean.setPath(path);
bean.setPathFlag(pathe.attributeValue("flag"));
bean.setFile(file);
xmltable.put(code, bean);
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
lastModifyTime = _lastModifyTime;
}
} catch (FileNotFoundException e) {
System.out.println("找不到文件:" + configPath + ";ERROR:"
+ e.getMessage());
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
//System.out.println("======xmltable size:" + xmltable.size());
return isReload;
}
/**
* @title: getPropPath
* @description:获取用户配置的Properties文件路径
* @param bean
* @return 参数说明
* @date 2009 Dec 25, 2009 7:40:41 PM
* @version Ver 1.0
* @since Ver 1.0
*/
private static String getPropPath(PropConfigBean bean) {
final String subPath=propertiesSubPath;
String path = bean.getPath();
String pathFlag = bean.getPathFlag();
String file = "";
// 如果没有配置路径则路径为classes下的config
if (path == null || "null".equals(path) || path.trim().length()==0) {
file += StrUtil.getClassesPath() + subPath;
} else {
if(path.startsWith("/")){
path=path.substring(1);
}
if(!path.endsWith("/")){
path=path+"/";
}
if ("1".equals(pathFlag)) {// 假如是全路径
file += path;
} else {
file += StrUtil.getClassesPath() + subPath + path;
}
}
file = file + bean.getFile();
//System.out.println("file:"+file);
return file;
}
/**
* 检测对应编码的Properties文件有没有修改
*
* @param code
*/
private static void initProp(String code) {
boolean reload = initXML();
InputStream in = null;
try {
if (propMap == null || reload) {
//System.out.println("======初始化MAP");
if(propMap!=null){
propMap.clear();
}
propMap = new HashMap();
Iterator iter = xmltable.keySet().iterator();
while (iter.hasNext()) {
String key = (String) iter.next();
PropConfigBean bean = (PropConfigBean) xmltable.get(key);
String file = getPropPath(bean);
long mdfiTime = new File(file).lastModified();
// 如果是第一次加载或文件时间更改重新载入
in = new BufferedInputStream(new FileInputStream(file));
Properties properties = new Properties();
properties.load(in);
PropBean pb = new PropBean();
pb.setFile(file);
pb.setMdfiTime(mdfiTime);
pb.setProp(properties);
propMap.put(key, pb);
}
} else {
// if (propMap.size() != xmltable.size()) {
// } else {
PropBean bean = (PropBean) propMap.get(code);
long mdfiTime = new File(bean.getFile()).lastModified();
if (bean.getMdfiTime() != mdfiTime) {
//System.out.println("======重新加载" + bean.getFile());
in = new BufferedInputStream(new FileInputStream(bean.getFile()));
Properties properties = new Properties();
properties.load(in);
bean.setMdfiTime(mdfiTime);
bean.setProp(properties);
propMap.put(code, bean);
}
// }
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
in.close();
} catch (Exception e) {
}
}
}
/**
* @title: getProperties
* @description:接口
* @param code
* @return 参数说明
* @date 2009 Dec 25, 2009 7:41:22 PM
* @version Ver 1.0
* @since Ver 1.0
*/
public static Properties getProperties(String code) {
initProp(code);
PropBean bean = (PropBean) propMap.get(code);
return bean!=null?bean.getProp():null;
}
private static class PropBean {
private Properties prop;
private long mdfiTime;
private String file;
public Properties getProp() {
return prop;
}
public void setProp(Properties prop) {
this.prop = prop;
}
public long getMdfiTime() {
return mdfiTime;
}
public void setMdfiTime(long mdfiTime) {
this.mdfiTime = mdfiTime;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
}
private static class PropConfigBean {
private String code;
private String path;
private String pathFlag;
private String file;
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getPathFlag() {
return pathFlag;
}
public void setPathFlag(String pathFlag) {
this.pathFlag = pathFlag;
}
}
public static void main(String[] args) {
System.out.println(getProperties("macro").get("head_replace_chars"));
System.out.println(xmltable.size());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
工具类:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class StrUtil {
/**
* @title: isWindows
* @description:检测是不是windows系统
* @return 参数说明
* @date 2009 Dec 25, 2009 6:10:09 PM
* @version Ver 1.0
* @since Ver 1.0
*/
public static boolean isWindows(){
return System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1;
}
/**
* @title: getClassesPath
* @description:获取工程中classes目录,以"/"结尾
* @return 参数说明
* @date 2009 Nov 24, 2009 4:16:07 PM
* @version Ver 1.0
* @since Ver 1.0
*/
public static String getClassesPath(){
String classPath=StrUtil.class.getResource("/").getPath();
if (isWindows()&& classPath.startsWith("/")) {
classPath = classPath.substring(1);
}
return classPath;
}
/**
* @title: readXML
* @description:读取XML文件返回文档对象
* @param filename
* @param code
* @return
* @throws FileNotFoundException
* @throws DocumentException 参数说明
* @date 2009 Dec 25, 2009 4:36:31 PM
* @version Ver 1.0
* @since Ver 1.0
*/
public static Document readXML(String filename, String code)
throws FileNotFoundException, DocumentException {
SAXReader saxReader = new SAXReader();
//此处用FileInputStream而非FileReader(newFile(filename)),用UTF8编码保存文件修改后中文乱码的问题
Document doc = saxReader.read(new FileInputStream(filename),code);
return doc;
}
/**
* @title: xmlString
* @description:转入XML文件路径返回XML内容字符串
* @param fileXML文件路径包括文件名
* @return
* @throws DocumentException
* 参数说明
* @date 2009 Nov 25, 2009 9:25:06 AM
* @version Ver 1.0
* @throws FileNotFoundException
* @since Ver 1.0
*/
public static String xmlString(String file) throws DocumentException, FileNotFoundException {
Document document = readXML(file,"UTF-8");
return document.asXML();
}
/**
* @title: getXmlString
* @description:转入自己的XML路径读出XML内容,路径从resultxml后面开始
* @param xx/xxx.xml,如macro/a.xml
* @return XML文件内容
* @date 2009 Nov 25, 2009 9:25:37 AM
* @version Ver 1.0
* @since Ver 1.0
*/
public static String getXmlString(String file) {
try {
if(file==null){
return null;
}
if(file.startsWith("/")){
file=file.substring(1);
}
return xmlString (getClassesPath()+"resultxml/"+file);
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
配置文件PropertiesConfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<genius>
<property>
<!--编码唯一-->
<code>webservice</code>
<!--property路径,不填默认classes下,flag是否是全路径:1是;0不是,不是时在classes/后面追加路径-->
<path flag="0">config/</path>
<!--文件名-->
<file>webService.properties</file>
<!--文件结束使用时间,不填永不过期,时间格式:yyyy-MM-dd-->
<endtime>2999-12-31</endtime>
</property>
</genius>