近来看到项目中使用apache的开源框架configuration,感觉蛮不错的,代码简洁清爽,让人为之一亮。忍不住下载下来学习一下。
以前配置都需要自己写读取配置文件的类,然后封装到多个对象中去,现在好了,configuration框架帮你做好了一切。configuration可以读取各种各样的配置文件,包括system,properties,xml,ini,jndi等等,对于java程序员来说,最主要的当然是xml形式的配置文件了。
首先下载最新的jar包和依赖包,然后创建一个java工程,把jar包添加到类路径里面去,就可以开始测试了。我所下载的jar包有:
commons-configuration-1.6.jar
commons-beanutils-1.8.0.jar
commons-collections-3.2.jar
commons-digester-1.8.jar
commons-lang-2.3.jar
commons-logging-1.0.4.jar
OK,万事大吉,可以开始编程测试了。
测试代码:
package com.william.configuration;
import java.util.List;
import java.util.Iterator;
import org.apache.commons.configuration.*;
public class ConfigurationTest
{
public static void main(String[] args)
{
try
{
long start = System.currentTimeMillis();
Configuration config = null;
// 加载配置文件(第一种方式)
config = new XMLConfiguration("config.xml");
long loadtime = System.currentTimeMillis();
// 打印获取的属性
System.out.println(config.getString("colors.background"));
System.out.println(config.getString("colors.text"));
System.out.println(config.getString("colors.header"));
System.out.println(config.getString("colors.link[@normal]"));
System.out.println(config.getInt("rowsPerPage"));
System.out.println(config.getString("colors.default"));
List<String> buttonNames = config.getList("buttons.name");
for (Iterator<String> iter = buttonNames.iterator(); iter.hasNext();)
{
String name = iter.next();
System.out.println(name);
}
System.out.println("加载配置的时间 :" + (loadtime - start));
System.out.println("获取属性的时间 :" + (System.currentTimeMillis() - loadtime));
}
catch (ConfigurationException e)
{
e.printStackTrace();
}
}
}
config.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?> <gui-definition> <colors> <background>#background</background> <text>#text</text> <header>#header</header> <link normal="link" visited="#800080"/> <default>${colors.header}</default> </colors> <rowsPerPage>15</rowsPerPage> <buttons> <name>OK,Cancel,Help</name> </buttons> <numberFormat pattern="###\,###.##"/> </gui-definition>
执行结果为:
#background
#text
#header
link
15
#header
OK
Cancel
Help
加载配置的时间 :156
获取属性的时间 :32
从以上测试代码和结果可以看出,使用configuration加载xml配置文件是非常简单的,一句话就可以了:
config = new XMLConfiguration("config.xml");
之后,就可以获取配置文件中的配置了。从配置文件和打印的结果我们看出,获取配置时忽略了跟元素,直接从二级元素开始,然后以"."来链接各个嵌套的元素,一直到叶子节点。可以获取int、String、List、short、long等java中常见的数据类型(当然要和配置文件中的类型相匹配,要不然要出转换错误的异常了)。有趣的是,configuration还支持${}表达式,我们看到default这个配置,它其实是引用的header这个配置,这样,当header改变时,default就变了。不过如果别人不熟悉这个框架的话,光看配置文件是很容易迷惑的,所以最好不要这样来进行配置。
你也许注意到了,加载配置文件的代码行我加了一行注释,说是第一种加载方式,那么还有什么其他的加载方式吗?当然,现在将try里面换成如下的代码块:
long start = System.currentTimeMillis();
// 加载配置文件(第二种方式,加载不同的配置文件)
CompositeConfiguration comp_config = new CompositeConfiguration();
comp_config.addConfiguration(new SystemConfiguration());
comp_config.addConfiguration(new XMLConfiguration("config.xml"));
comp_config.addConfiguration(new PropertiesConfiguration("config.properties"));
long loadtime = System.currentTimeMillis();
// 打印获取的属性
System.out.println(comp_config.getString("colors.background"));
System.out.println(comp_config.getString("colors.text"));
System.out.println(comp_config.getString("colors.header"));
System.out.println(comp_config.getString("colors.link[@normal]"));
System.out.println(comp_config.getInt("rowsPerPage"));
System.out.println(comp_config.getString("colors.default"));
System.out.println(comp_config.getString("username"));
System.out.println("加载配置的时间 :" + (loadtime - start));
System.out.println("获取属性的时间 :" + (System.currentTimeMillis() - loadtime));
config.properties:
username=william password=iloveyou
执行的结果为:
#background
#text
#header
link
15
#header
william
加载配置的时间 :187
获取属性的时间 :31
现在我们用的是一个CompositeConfiguration,顾名思义,这是一个组合配置类,使用此类,将不同的配置文件加载到一个类里面来。这里加载了一个config.xml文件和一个config.properties文件。
另外还有一种加载配置文件的方式,现在把第一种加载方式代码处config = new XMLConfiguration("config.xml"); 改成如下的代码:
......
// 加载配置文件(第三种方式,通过配置工厂加载不同的配置文件)
ConfigurationFactory fty = new ConfigurationFactory("init.xml");
Configuration config = fty.getConfiguration();
......
init.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="config.properties"/> <xml fileName="config.xml"/> </configuration>
执行结果为:
#background
#text
#header
link
15
#header
OK
Cancel
Help
加载配置的时间 :391
获取属性的时间 :31
可以看出,这种加载方式同样可以加载多个配置文件,不过耗时却比第一、二种方式多了一倍。比较这三种方式,最灵活的是第三种采用工厂的方式,代码写好后,如果要添加或删减配置文件,根本不需要动代码了,只是加载时间稍微慢了一点,不过一般来说,这点时间大多数项目还是给得起。第二种则比较中性,通过Configuration的子类CompositeConfiguration来加载不同的配置文件,速度还比较快。第一种方式则速度最快,不过缺点是只能加载单一的配置文件,如果能确保配置文件单一稳定,这种方式也是蛮不错的。
另外,apache网站上有说过,所有的配置文件操作都是非线程安全的,这点就得由我们自己去控制了。