apache commons-configuration包读取配置文件
1、pom依赖添加
<!-- 配置文件读取 --> <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.10</version> </dependency>
2、读取.properties文件
使用PropertiesConfiguration配置类,主要示例代码如下:
public static final String fileName = "test.properties"; public static PropertiesConfiguration cfg = null; static { try { cfg = new PropertiesConfiguration(fileName); } catch (ConfigurationException e) { e.printStackTrace(); } // 当文件的内容发生改变时,配置对象也会刷新 cfg.setReloadingStrategy(new FileChangedReloadingStrategy()); } /** * 读String * @param key * @return */ public static String getStringValue(String key) { return cfg.getString(key); } /** * 读int * @param key * @return */ public static int getIntValue(String key) { return cfg.getInt(key); } /** * 读boolean * @param key * @return */ public static boolean getBooleanValue(String key) { return cfg.getBoolean(key); } /** * 读List */ public static List<?> getListValue(String key) { return cfg.getList(key); } /** * 读数组 */ public static String[] getArrayValue(String key) { return cfg.getStringArray(key); }
test.properties可以如下定义:
name=king port=21 flag=true interest=guitar,piano
之后就可以用给定的一些读取方法操作了
String name = CGPropetiesUtil.getStringValue("name");
System.out.println("String:" + name);
3、读取.xml文件
使用XMLConfiguration配置类
主要代码
public static final String fileName = "test.xml"; public static XMLConfiguration cfg = null; static { try { cfg = new XMLConfiguration(fileName); } catch (Exception e) { e.printStackTrace(); } // 配置文件 发生变化就重新加载 cfg.setReloadingStrategy(new FileChangedReloadingStrategy()); } public static String getStringValue(String key) { return cfg.getString(key); } public static int getIntValue(String key) { return cfg.getInt(key); }
test.xml定义如下:
<?xml version="1.0" encoding="UTF-8"?> <config> <database> <url>127.0.0.1</url> <port>1521</port> <login>admin</login> <password>admin</password> </database> </config>
测试操作同上。
4、对于一个文件来说,他的操作就对应一个配置类,而不能使用同一个配置类操作多个文件,否则它只以读取的第一个为操作对象。针对这种情况,可以写成一个通用的读取工具,简单示例如下:
public class CGCommonUtil { /** * 一个文件对应一个Configuration */ public static Map<String, Configuration> configMap = new ConcurrentHashMap<String, Configuration>(); /** * 文件后缀 */ private static final String SUFFIX_PROPERTIES = ".properties"; private static final String SUFFIX_XML = ".xml"; public static Configuration getConfig(String fileName) { if (!configMap.containsKey(fileName)) { CGCommonUtil.initConfig(fileName); } Configuration cfg = configMap.get(fileName); if (null == cfg) { throw new IllegalArgumentException("cfg is null"); } return cfg; } private static void initConfig(String fileName) { Configuration cfg = null; try { if (fileName.endsWith(SUFFIX_XML)) { cfg = new XMLConfiguration(fileName); } else if (fileName.endsWith(SUFFIX_PROPERTIES)) { cfg = new PropertiesConfiguration(fileName); } } catch (ConfigurationException e) { e.printStackTrace(); } if (null != cfg) { configMap.put(fileName, cfg); } else { System.out.println("cfg is null"); } } /** * 读String * @param key * @return */ public static String getStringValue(Configuration cfg, String key) { return cfg.getString(key); } /** * 读int * @param key * @return */ public static int getIntValue(Configuration cfg, String key) { return cfg.getInt(key); } /** * 读boolean * @param key * @return */ public static boolean getBooleanValue(Configuration cfg, String key) { return cfg.getBoolean(key); } /** * 读List */ public static List<?> getListValue(Configuration cfg, String key) { return cfg.getList(key); } /** * 读数组 */ public static String[] getArrayValue(Configuration cfg, String key) { return cfg.getStringArray(key); } public static void main(String[] args) { Configuration config = getConfig("test.properties"); String name1 = getStringValue(config, "name"); } }
以上可以作为一个通用的读取工具,为每一个文件都设置了一个相应的配置操作类,如果考虑本地缓存影响会影响内存的话可以考虑定时删除缓存数据操作
5、Configuration读取文件源原
入口类ConfigurationUtils
主要涉及的方法如下:
locateFromClasspath方法:
static URL locateFromClasspath(String resourceName) { URL url = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader != null) { url = loader.getResource(resourceName); if (url != null) { LOG.debug("Loading configuration from the context classpath (" + resourceName + ")"); } } if (url == null) { url = ClassLoader.getSystemResource(resourceName); if (url != null) { LOG.debug("Loading configuration from the system classpath (" + resourceName + ")"); } } return url; }
首先它通过获取了当前线程的一个类加载器,通过加载器的getResouce方法去类加载器找到resourceName这个文件
getResouce方法:
public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name); } return url; }
先去父节点的loader去加载资源文件,如果找不到,则会去BootstrapLoader中去找,如果还是找不到,才调用当前类的classLoader去找。这也就是JDK类加载的双亲委派模型。
getInputStream方法:
public InputStream getInputStream(URL url) throws ConfigurationException { File file = ConfigurationUtils.fileFromURL(url); if (file != null && file.isDirectory()) { throw new ConfigurationException("Cannot load a configuration from a directory"); } else { try { return url.openStream(); } catch (Exception var4) { throw new ConfigurationException("Unable to load the configuration from the URL " + url, var4); } } }
调用url的openStream()方法去获得此文件的输入流
GItHub源码参照