使用Apache Commons Configuration讀取配置信息

在項目中使用一些比較新的庫總會給你帶來很多快樂,在這篇文章中,我將會給你介紹一個在Java中讀取配置文件的框架——Apache Commons Configuration framework. 

你會瞭解到

    ·從XML文件中獲取數據
    ·訪問環境變量
    ·連接不同類型的配置信息(基於XML的,基於環境變量的,等等)

    ·在程序改變後自動重新加載配置。

    在我們的示例中將會使用XML文件和環境變量的兩種方式存儲一個數據庫的配置信息(開發、測試、產品,等等)。接下來你將會看到具體的內容,但是首先先配置一下Maven。

Maven設置

我們的示例程序需要在pom.xml文件中添加如下依賴:
<dependencies>
    <dependency>
        <groupId>commons-configuration</groupId>
        <artifactId>commons-configuration</artifactId>
        <version>1.8</version>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.8.0</version>
    </dependency>
    <dependency>
        <groupId>commons-jxpath</groupId>
        <artifactId>commons-jxpath</artifactId>
        <version>1.3</version>
    </dependency>
</dependencies>


簡單的數據庫配置

    設想我們有一個簡單的數據庫配置信息存儲在XML文件中:
<?xmlversion="1.0"encoding="UTF-8"?>
<!-- const.xml -->
<config>
    <database>
        <url>127.0.0.1</url>
        <port>1521</port>
        <login>admin</login>
        <password>pass</password>
    </database>
</config>
 
    爲了拿到url和port我們用如下的代碼:
XMLConfiguration config =new XMLConfiguration("const.xml");
// 127.0.0.1
config.getString("database.url"); 
// 1521
config.getString("database.port");
 
    XMLConfiguration是一個Apache Commons類,他可以從指定的配置文件中加載內容,並且提供一個很好的以指定的點的方式得到存儲的值。例如例子中的表達式database.port映射到xml文件中的 config/database/port節點的值“1521”。當然還有很多方式獲取數據。這裏有一些基本的用法:
getBoolean
getByte
getDouble
getFloat
getInt
getInteger
getList
getLong
getStringArray
    你可通過查看Apache Commons的JavaDoc查看更多的使用方式。


將如上配置擴展一步

    設想,過了一會我們想配置多個數據庫,我們可以在配置文件中這樣寫:
<?xmlversion="1.0"encoding="UTF-8"?>
<!-- const.xml -->
<config>
    <databases>
        <database>
            <name>dev</name>
            <url>127.0.0.1</url>
            <port>1521</port>
            <login>admin</login>
            <password>pass</password>
        </database>
        <database>
            <name>production</name>
            <url>192.23.44.100</url>
            <port>1521</port>
            <login>admin</login>
            <password>not-so-easy-pass</password>
        </database>
    </databases>
</config>
    現在我們要訪問url數據我們可以這樣:
XMLConfiguration config =new XMLConfiguration("const.xml");
 
// 127.0.0.1
config.getString("databases.database(0).url");
 
// 192.23.44.100
config.getString("databases.database(1).url");
    你可以看到這次多了參數,0代表第一個,1代表第二個。


XPath表達式

    定點的訪問方式沒問題,但是只是在一些簡單的情況下,對於複雜的真實的狀況來講,我們可能需要使用XPath表達式語言。這裏的主要優點是,即便你使用了XML的高級查詢,程序看起來仍然比較簡潔易懂。
XMLConfiguration config =new XMLConfiguration("const.xml");
config.setExpressionEngine(new XPathExpressionEngine());
 
// 127.0.0.1
config.getString("databases/database[name = 'dev']/url");       
 
// 192.23.44.100
config.getString("databases/database[name = 'production']/url");
    這裏是上面兩個XPath表達式查詢的一個解釋:


訪問環境變量

    在Apache Commons Configuration的幫助下你可以輕鬆的訪問到系統的環境變量。下面是訪問系統中ENV_TYPE變量的方法:
EnvironmentConfiguration config =new EnvironmentConfiguration();
config.getString("ENV_TYPE");
    假設變量ENV_TYPE已經設置好了,想看上面的程序是否運行正確,你可以在控制檯運行如下腳本:
echo %ENV_TYPE%        # for Windows
# or...
echo $ENV_TYPE         # for Linux/Mac OS
你將會看到ENV_TYPE的值。


聯合配置

    讓我們總結一下我們瞭解的東西,下面的getDbUrl方法做如下事情:
    ·檢查系統環境變量中叫做ENV_TYPE的值。
    ·如果值是dev或者produtcion就返回相應的數據庫url
    ·如果變量沒有配置就拋出異常。
public String getDbUrl() throws ConfigurationException {
    EnvironmentConfiguration envConfig =new EnvironmentConfiguration();
    String env = envConfig.getString("ENV_TYPE");
    if("dev".equals(env) ||"production".equals(env)) {
        XMLConfiguration xmlConfig =new XMLConfiguration("const.xml");
        xmlConfig.setExpressionEngine(new XPathExpressionEngine());
        String xpath ="databases/database[name = '"+ env +"']/url";
        return xmlConfig.getString(xpath);
    }else{
        String msg ="ENV_TYPE environment variable is "+
                     "not properly set";
        throw new IllegalStateException(msg);
    }
}


集中你的配置

    對每個不同的需要配置的對象創建多個配置比較煩。假如我們想添加其他的基於XML的配置,我們會怎麼搞?我們需要創建另一個XMLConfiguration對象,這會給管理帶來很多麻煩。一個解決辦法是把配置文件信息集中到一個單個XML文件中。下面是一個例子:
<?xmlversion="1.0"encoding="UTF-8"?>
<!-- config.xml -->
<configuration>
  <env/>
  <xmlfileName="const.xml"/>
</configuration>
    你需要使用DefaultConfigurationBuilder類,最終版本的getDbUrl方法看起來像這樣:
public String getDbUrl()throws ConfigurationException {
    DefaultConfigurationBuilder builder =
        new DefaultConfigurationBuilder("config.xml");
    boolean load =true;
    CombinedConfiguration config = builder.getConfiguration(load);
    config.setExpressionEngine(new XPathExpressionEngine());
    String env = config.getString("ENV_TYPE");
    if("dev".equals(env) ||"production".equals(env)) {
        String xpath ="databases/database[name = '"+ env +"']/url";
        return config.getString(xpath);
    }else{
        String msg ="ENV_TYPE environment variable is "+
                     "not properly set";
        throw new IllegalStateException(msg);
    }
}


自動重新加載

    Apache Commons Configuration有很多非常酷的特性。其中一個就是當基於文件的配置變化的時候自動加載,因爲我們可以設置加載策略。框架會輪詢配置文件,當文件的內容發生改變時,配置對象也會刷新。你可以用程序控制:
XMLConfiguration config =new XMLConfiguration("const.xml");
ReloadingStrategy strategy =new FileChangedReloadingStrategy();
strategy.setRefreshDelay(5000);
config.setReloadingStrategy(strategy);
    或者把他寫到主配置文件中:
<?xmlversion="1.0"encoding="UTF-8"?>
<!-- config.xml -->
<configuration>
  <env/>
  <xmlfileName="const.xml">
    <reloadingStrategyrefreshDelay="5000"config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
  </xml>
</configuration>
    每五秒框架都檢查一下配置文件有沒有改變。


最後

    我個人用來管理需要配置的代碼的時候的選擇是使用Apache Commons。我希望這篇文章可以讓你相信這個框架可以提供一個非常有用的接口用來訪問你的靜態數據。最後需要說的一點,這篇文章的內容只是這個框架的功能的一部分。此框架一些其他的有趣的功能是:
    ·從不同的數據源裝載配置信息,例如properties文件、ini文件、數據庫等等。
    ·給配置對象增加新的屬性,並把它回存到文件中。
    ·監聽配置對象改變的事件。(這點可以讓你在配置發生改變的時候及時作出處理)

    ·自動解析配置文件的實際路徑(不管你是把它放在程序文件夾下還是一個jar中。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章