结合Commons Configuration和Maven进行工程配置管理

本文源自目前公司中对一些项目的总结。

实际问题:每个工程都会包含多套配置环境,包括开发环境,测试环境,沙盒环境以及生产环境,而每一套环境都对应着不同的配置参数。

本文以一个非web工程举例,使用到了Commons Configuration + Maven管理配置,并包括一个完整的配置文件读取工具类。整理一下分享出来。

---------------------------------------

第一部分:Commons Configuration功能简记

Commons Configuration是Apache下的一个java配置管理类库项目。

支持的配置文件可以是以下多种格式:

Properties files、XML documents、Property list files(.plist)、JNDI、JDBC Datasource、System properties、Applet parameters、Servlet parameters。

 

基本功能简记:

一、Properties:

1、include = colors.properties //可以在properties中引用properties

2、Lists and arrays:

colors.pie = #FF0000, #00FF00, #0000FF

config.getStringArray("colors.pie") //获取数组值

3、save properties:

config.save("usergui.backup.properties"); //保存文件

4、Special Characters and Escaping:特殊字符

5、Custom properties readers and writers:自定义属性文件处理规则(key带空格情况)

 

二、File-based Configurations:

1、Automatic Saving:  //setProperties时自动保存

config.setAutoSave(true);

2、Automatic Reloading: //重新加载文件

config.setReloadingStrategy(new FileChangedReloadingStrategy());

 

三、Hierarchical properties:

1、load xml file.  //加载xml文件

2、Accessing structured properties:  //访问某元素

tables.table(0).name

tables.table(0)[@tableType]

HierarchicalConfiguration sub = config.configurationAt("tables.table(0)");

String tableName = sub.getString("name");  // only need to provide relative path

List<Object> fieldNames = sub.getList("fields.field.name");

3、Escaping special characters:   //特殊字符,如xml的key中带.

int testVal = config.getInt("test..value");

4、expression engine/XPATH

5、Validation of XML configuration files

 

四、Composite Configuration

Setting Up Defaults

Saving Changes

 

五、Configuration Events:

listeners are notified whenever the configuration's data is changed.

This provides an easy means for tracking updates on a configuration.

1、Configuration listeners

2、Error listeners

 

六、Utility classes:

1、Copy a configuration

2、Converting a flat configuration into a hierarchical one: //转换flag为hierarchical结构

PropertiesConfiguration flatConfig = new PropertiesConfiguration();

flatConfig.load(...);

HierarchicalConfiguration hc = ConfigurationUtils.convertToHierarchical(flatConfig);

3、Handling of runtime exceptions:

throws a runtime exception (namely a ConfigurationRuntimeException) on each received error event.

以上只是部分功能。

详情见官方参考资料:

user guide: http://commons.apache.org/configuration/userguide/user_guide.html

java api doc:http://commons.apache.org/configuration/apidocs/index.html

其它类似资料:

commons configuration包使用:

http://www.360doc.com/content/11/0406/16/2749105_107609102.shtml

 

第二部分:一个配置文件工具类的封装

曾经写过一篇blog,一个数据库配置文件工具类:http://shensy.iteye.com/blog/1566651

这次,完善了一下上次那个程序,写了个更通用的实现。

Java代码   收藏代码
  1. public final class ConfigProject {  
  2.       
  3.     public static final Logger LOGGER = LoggerFactory.getLogger(ConfigProject.class);  
  4.       
  5.     public static CompositeConfiguration COMMON_CONFIG = new CompositeConfiguration();  
  6.       
  7.     public static void init(String confDir)  
  8.     {  
  9.         //加载顺序是从前到后,一个属性在先加载的配置中查找,没有则在后面的配置中查找.  
  10.         COMMON_CONFIG.addConfiguration(loadPropertiesConfiguration(confDir,"settings.properties"));  
  11.         COMMON_CONFIG.addConfiguration(loadXMLConfiguration(confDir,"data.xml"));  
  12.     }  
  13.       
  14.     /** 
  15.      * 获取properties配置文件属性 
  16.      */  
  17.     public static PropertiesConfiguration loadPropertiesConfiguration(String confDir,String fileName){  
  18.         PropertiesConfiguration fileConfiguration = new PropertiesConfiguration();  
  19.         try{  
  20.             fileConfiguration.setReloadingStrategy(getFileChangedReloadingStrategy());  
  21.             //加载文件前设置分隔符失效(不使用任何分隔符).  
  22.             fileConfiguration.setDelimiterParsingDisabled(true);  
  23.             //加载文件前设置分割符,默认为逗号(,)如果配置项中包含分隔符就会被分割.  
  24.             //fileConfiguration.setListDelimiter('_');  
  25.             //如果用户没有指定绝对路径:加载文件顺序为current directory,user home directory,classpath.  
  26.             fileConfiguration.load(getConfigURL(confDir,fileName));  
  27.         }catch(Exception e){  
  28.             LOGGER.error("failed to load properties config:" + fileName, e);  
  29.         }  
  30.         return fileConfiguration;  
  31.     }  
  32.       
  33.     /**  
  34.      * 获取XML配置文件属性 
  35.      */  
  36.     public static XMLConfiguration loadXMLConfiguration(String confDir,String fileName){  
  37.         XMLConfiguration xmlConfiguration = new XMLConfiguration();  
  38.         try{  
  39.             xmlConfiguration.setReloadingStrategy(getFileChangedReloadingStrategy());  
  40.             xmlConfiguration.setDelimiterParsingDisabled(true);  
  41.             xmlConfiguration.setAttributeSplittingDisabled(true);  
  42.             xmlConfiguration.load(getConfigURL(confDir,fileName));  
  43.         }catch(Exception e){  
  44.             LOGGER.error("failed to load xml config:" + fileName, e);  
  45.         }  
  46.         return xmlConfiguration;  
  47.     }  
  48.       
  49.     /** 
  50.      * 通过properties文件设置system属性. 
  51.      */  
  52.     public static void setSystemConfigurationByProp(String fileName) throws Exception{  
  53.         SystemConfiguration systemConfiguration = new SystemConfiguration();  
  54.         systemConfiguration.setSystemProperties(fileName);  
  55.     }  
  56.       
  57.     private static URL getConfigURL(String confDir,String fileName) throws Exception{  
  58.         File file = new File(confDir + "/" + fileName);  
  59.         URL url = null;  
  60.         if (file.exists()) {  
  61.             url = file.toURI().toURL();  
  62.         } else {  
  63.             /** 
  64.              * ConfigurationUtils.locate: 
  65.              * Return the location of the specified resource by searching 
  66.              * the user home directory, the current classpath and the system classpath. 
  67.              */  
  68.             url = ConfigurationUtils.locate(confDir,fileName);  
  69.             LOGGER.debug("config file url:"+url);  
  70.         }  
  71.         return url;  
  72.     }  
  73.       
  74.     private static FileChangedReloadingStrategy getFileChangedReloadingStrategy(){  
  75.         FileChangedReloadingStrategy reloadingStrategy = new FileChangedReloadingStrategy();  
  76.         reloadingStrategy.setRefreshDelay(10000);//10s  
  77.         return reloadingStrategy;  
  78.     }  
  79.       
  80.     public static void main(String[] args){  
  81.         ConfigProject.init("./conf");  
  82.     }  
  83. }  

上面的工具类实现了对一个properties文件和一个xml文件的加载,并设置自动重新加载时间为10s,并设置默认分隔符失效。

具体项目中可根据需要修改init中需要加载的配置文件和confDir路径即可(本例中为./conf)。

 

至于confDir配置文件夹路径,起到一个覆盖配置的作用:

因为本项目部署时采用jar形式部署,使用Maven管理,配置文件放在src/main/resources下。打jar包时会将src/main/resources下的配置文件直接打到jar中。但是如果线上部署时需要修改配置文件的话,就需要重新打包,比较麻烦。而使用confDir配置文件夹路径的作用是先加载confDir路径下的配置文件,如果没有该路径或没有配置文件再加载jar包中的。这样只要在部署路径下建一个conf文件夹,将修改后的同名配置文件放进去,即可覆盖jar中的配置。

 

第三部分:结合Maven实现配置管理

在Maven中的pom.xml文件中配置如下(举例):

首先,添加依赖:

Xml代码   收藏代码
  1. <dependency>  
  2.       <groupId>commons-configuration</groupId>  
  3.       <artifactId>commons-configuration</artifactId>  
  4.       <version>1.6</version>  
  5. </dependency>  

其次:

Xml代码   收藏代码
  1. <profiles>  
  2.       <profile>  
  3.        <id>dev</id>  
  4.        <activation>  
  5.                    <activeByDefault>true</activeByDefault>  
  6.            </activation>  
  7.        <properties>  
  8.            <dburl><![CDATA[dburl_dev]]></dburl>  
  9.            <username>username1</username>  
  10.                    <password>dev_password</password>  
  11.        </properties>  
  12.     </profile>  
  13.         <profile>  
  14.        <id>prod</id>  
  15.        <properties>  
  16.            <dburl><![CDATA[dburl_prod]]></dburl>  
  17.            <username>username2</username>  
  18.                    <password>prod_password</password>  
  19.        </properties>  
  20.     </profile>  
  21. </profiles>  

在properties文件中或xml文件中使用${}替换实际的value:

Xml代码   收藏代码
  1. dburl=${dburl}  
  2. <username>${username}</username>  
  3. <password>${password}</password>   

以上建立了2套配置,一套是dev环境的,一套是prod环境的。

在用Maven命令打包时指定环境:

mvn clean package -Pdev

mvn clean package -Pprod

mvn install(将构建包安装到local repository)

mvn install -DskipTests -Pdev

mvn install -DskipTests -Pprod

(关于maven的pom.xml配置文件和maven命令的详细介绍后续会专门写一篇blog总结整理出来。)

OK,再看看打好的包,比如test.jar中的配置文件是不是对应的dev或prod的配置了。

部署时,如果test.jar部署在~/local/Test下,那么就可以在Test下在建立一个文件夹conf,并在~/local/Test/conf下面放置与jar中同名的xml或properties配置文件,这样就可以直接覆盖掉jar中相同key的配置了,相当方便。

希望对看到的人有所帮助,也希望大家多提意见。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值