DeltaSpikeのLow-level ConfigurationsとProjectStageについて

DeltaSpikeにはデフォルトで設定情報を設定もと(設定ソース)から読み込むための仕組みが存在します。ドキュメントにはLow-level Configurationsとして紹介されています。

簡単にいうと、システムプロパティや、環境変数に設定した情報を読み込む仕組みです。

DeltaSpikeではデフォルトで次の4つの設定ソースから設定情報を取得することが可能です。


システムプロパティ
環境変数
ローカルJNDI
プロパティファイル

この設定ソースはDeltaSpike内で優先順序が定義されており、デフォルトでは上記で示した順序となっています。
なお、プロパティファイルにアプリケーション固有の設定を行う場合は、META-INF/apache-deltaspike.propertiesを作成し、そのファイル内に任意の設定情報を定義します。

設定ソースにアクセスするクラスはConfigResolverで、このクラスのgetPropertyValueもしくはgetAllPropertyValuesメソッド(いずれもstatic)から、設定値を特定するためのキーを引数に渡すことで設定値を取得できます。

まず、それぞれのメソッドについて簡単に説明します。

  • getPropertyValue(String key)

キーを引数に設定ソースに定義されているキーに紐付く設定値を返します。ただし、同一キーの設定情報がシステムプロパティとプロパティファイル双方に存在する場合は優先順でシステムプロパティの設定値が返されます。

  • getAllPropertyValues(String key)

キーを引数に設定ソースに定義されているキーに紐付く設定値をリストで返します。このメソッドは設定ソースを順番に検索し、そのキーと一致する情報が存在する場合、その設定値をリストに保存して、設定ソースをすべて検索後に結果を返します。

では実際にプログラムで検証を行ってみます。

まず、META-INFにapache-deltaspike.propertiesを作成し次のような適当な設定値を定義します。

apache-deltaspike.properties】


config.value1=value1
config.value2=value2
config.value3=value3

次にシステムプロパティを設定します。自分はJBoss7を利用しているのでJBoss7での設定例を示します。JBoss7をstandaloneモードで利用している場合は${JBOSS_HOME}/standalone/configuration配下のstandalone.xmlファイルのextensions定義直下に以下のように定義します。

<extensions>
    ...
</extensions>
<system-properties>
    <property name="config.value1" value="systemValue1"/>
</system-properties>

検証用のプログラムは次の通りです。

import java.util.List;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

import org.apache.deltaspike.core.api.config.ConfigResolver;

@Named
@RequestScoped
public class ConfigBean {

    private String key;
    
    private String value;
    
    private List<String> allValues;
    
    public String searchPropertyValue() {
        value = ConfigResolver.getPropertyValue(key);
        return "displaySingleConfigValue.xhtml";
    }
    
    public String searchAllPropertyValues() {
        allValues = ConfigResolver.getAllPropertyValues(key);
        return "displayAllConfigValues.xhtml";
    }
    ...
}

searchPropertyValueメソッドが実行されるとConfigResolver.getPropertyValueが呼び出され、キーに対応する単一設定値を取得します。searchAllPropertyValuesメソッドが実行されるとConfigResolver.getAllPropertyValuesが呼び出され、キーに対応する設定値すべてを設定ソースすべてから検索して結果をリストとして返します。

ではそれぞれのメソッドを実行するための検索Viewを次のように定義します。

【searchConfig.xhtm】

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:head>
        <title>Search configuration.</title>
    </h:head>
    <h:body>
        <h:outputText value="Input configuration key" style="font-style: italic; fontsize: 1.5em" />
        <h:form>
            <h:panelGrid columns="2">
                key : 
                <h:inputText value="#{configBean.key}" />
            </h:panelGrid>
            <br />
            <h:panelGrid columns="2">
                <h:commandButton value="Search single value" action="#{configBean.searchPropertyValue}" />
                <h:commandButton value="Search all value" action="#{configBean.searchAllPropertyValues}" />
            </h:panelGrid>
        </h:form>
    </h:body>
</html>

単一結果、および、全設定ソース検索結果を出力するViewをそれぞれ次のように定義します。

【displaySingleConfigValue.xhtml(単一結果出力用)】

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:head>
        <title>Single configuration value.</title>
    </h:head>
    <h:body>
        <h:panelGrid columns="2">
            Search key :
            <h:outputText value="#{configBean.key}" />
            Searched value :
            <h:outputText value="#{configBean.value}" />
        </h:panelGrid>
    </h:body>
</html>

【displayAllConfigValues.xhtml(全設定ソース検索結果出力用)】

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:head>
        <title>All configuration value.</title>
    </h:head>
    <h:body>
        <h:panelGrid columns="2">
            Search key :
            <h:outputText value="#{configBean.key}" />
        </h:panelGrid>
        <br />
        Searched all values :
        <br />
        <ui:repeat value="#{configBean.allValues}" var="val">
            <h:outputText value="#{val}" /><br />
        </ui:repeat>
    </h:body>
</html>

このアプリケーションをJBossにディプロイしてsearchConfig.xhtmにアクセスし、config.value1と入力して"Search single value"をクリックしてみてください。システムプロパティで設定した結果が以下のように出力されます。


Search key : config.value1
Searched value : systemValue1

今度は"Search all value"をクリックしてみてください。結果はシステムプロパティとapache-deltaspike.propertiesに設定したそれぞれの値が出力されます。


Search key : config.value1
Searched all values :
systemValue1
value1

この仕組みを利用するとアプリケーション固有もしくは環境固有の設定情報により、プログラムの振る舞いをうまく制御することが可能になります。また、以前@ExcludeとProjectStageを紹介した際にProjectStageの変更方法が不明と説明しましたが、このLow-level Configurationsの仕組みを利用して変更することが可能です。

DeltaSpkieにはProjectStageProducerというクラスが存在し、このクラスがProjectStageの決定を行う際にConfigResolverのgetPropertyValueメソッドからProjectStageの値をキー"org.apache.deltaspike.ProjectStage"で取得しています。
この結果がnullの場合にProjectStageがProductionとなる訳です。

従ってProjectStageを変更する場合は、「org.apache.deltaspike.ProjectStage=任意のProjectStage」として設定しておけばいいということになります。

では実際にシステムプロパティに「org.apache.deltaspike.ProjectStage=Development」となるように設定してJBossを再起動し、「DeltaSpikeのProjectStageと@Exclude」という記事で紹介したプログラムを動作させてみます。

【standalone.xmlシステムプロパティ設定例)】

<system-properties>
    <property name="org.apache.deltaspike.ProjectStage" value="Development"/>
    ...
</system-properties>

実行結果は次のようになると思います。


Now, It's Development stage.

なお、DeltaSpikeではデフォルトの設定ソース以外に独自の設定ソースを組み込み、その優先順序も変更することが可能なのですが、これはまた別の機会に紹介したいと思います。