在项目开发中,对于一些程序运行的参数可能经常需要根据实际情况修改或调整,所以这些参数我们不会在代码中写死,而是它们保存在properties(或xml)文件中,以方便修改。这时就需要智能加载要配置文件,如何智能加载,我想要的加载顺序:
1. jar包所在目录(加载jar包里的初始值)
2. 项目所在目录(调用jar的程序)
3. 用户工作目录(use.dir)
下面是完整的java代码:
package net.gdface.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
public class ConfigUtils {
/**
* 顺序加载不同位置的properties文件,加载顺序为:<br>
* 1.调用{@link ClassLoader#getResource(String)}方法在{@code clazz}所在位置查找,如果失败则抛出异常<br>
* 2.如果class在jar包中,则尝试读取在jar所在位置../confFolder/propFile,tomcat下即为WEB-INF/confFolder/propFile<br>
* 3.如果环境变量envVar定义,则从envVar指定的目录下读取propFile<br>
* 4.user.dir下查找confFolder/propFile加载配置<br>
* 后面的配置变量会覆盖前面的定义<br>
* @param propFile 要加载的properties文件名,为{@code null}或空时抛出异常 {@link IllegalArgumentException}
* @param confFolder popFile所在文件夹,{@code null}时使用默认值'conf'
* @param envVar 环境变量名 用于定义propFile位置,可为{@code null}
* @param clazz 用于获取 {@link ClassLoader}的类,为null时使用本类的class
* @param showProp 加载后是否显示所有值
* @return 返回加载后的{@link Properties}对象
*/
public static Properties loadAllProperties(String propFile, String confFolder, String envVar, Class<?> clazz, boolean showProp) {
if(null==propFile||propFile.isEmpty())
throw new IllegalArgumentException("the argument 'propFile' must not be null or empty");
if (null == confFolder)
confFolder = "conf";
if (null == clazz)
clazz = ConfigUtils.class;
final String fileSeparator = System.getProperty("file.separator");
String prop_path = confFolder.concat(System.getProperty("file.separator")).concat(propFile);
Properties props = new Properties();
Set<File> loaded_files = new HashSet<File>();
try {
URL url = clazz.getClassLoader().getResource(prop_path.replace(fileSeparator, "/"));
if(null==url)
throw new ExceptionInInitializerError(String.format("not found default properties %s", prop_path));
loadProperties(url, props);
} catch (Exception e) {
throw new ExceptionInInitializerError(String.format("fail to load default properties(加载默认配置文件失败) %s cause by %s", prop_path,
e.getMessage()));
}
try {
URL class_location = clazz.getProtectionDomain().getCodeSource().getLocation();
if (class_location.toString().endsWith(".jar")) {
File jar_parent = new File(class_location.getPath()).getParentFile().getParentFile();
if (null != jar_parent) {
File conf_file = new File(jar_parent, prop_path);
if (conf_file.isFile()) {
loadProperties(conf_file.toURI().toURL(), props);
loaded_files.add(conf_file);
}
}
}
} catch (Exception e) {
}
try {
if (envVar != null && !envVar.isEmpty()) {
String cf = System.getProperty(envVar);
if (null != cf&&!cf.isEmpty()) {
File env_file = new File(cf, propFile);
if (!loaded_files.contains(env_file)) {
loadProperties(env_file.toURI().toURL(), props);
loaded_files.add(env_file);
}
} else
log("not defined environment variable '%s'", envVar);
}
} catch (Exception e) {
}
try {
File propInUserDir = new File(System.getProperty("user.dir"), prop_path);
if (propInUserDir.isFile() && !loaded_files.contains(propInUserDir)) {
loadProperties(propInUserDir.toURI().toURL(), props);
loaded_files.add(propInUserDir);
}
} catch (Exception e) {
}
if(showProp)
props.list(System.out);
return props;
}
/**
* configure with the parameters given in the given url
*
* @param url
* the resource filename to be used
* @param props
* dest properties to add
* @throws IOException
*/
private static void loadProperties(URL url, Properties props) throws IOException {
if (null != url) {
InputStream is = null;
try {
props.load(is = url.openStream());
log("Load properties from %s", url.toString());
} finally {
if (is != null)
is.close();
}
}
}
private static void log(String format, Object ... args){
System.out.printf("[%s:%d]%s\n",
ConfigUtils.class.getSimpleName(),
Thread.currentThread() .getStackTrace()[2].getLineNumber(),
String.format(format, args));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
如果上面三个目录里文件存在相同的key,后面加载将覆盖前面的ps: this.class.getProtectionDomain().getCodeSource().getLocation()
如果直接执行.class文件那么会得到当前class的绝对路径:
file:/E:/melt/workspace/bpmsAnalysis/build/classes/
如果封装在jar包里面执行jar包那么会得到当前jar包的绝对路径:
file:/E:/melt/workspace/bpmsAnalysis/WebContent/WEB-INF/lib/JdbcUtils.jar
通过执行目录来决定把文件放src下,还是要WEB-INF下
转:http://blog.csdn.net/10km/article/details/52100365