M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

Typesafe Configを使ってみる

近ごろ(といってもすでに数年来)、ScalaやPlay Frameworkとともに存在感を増しているTypesafe社。同社が汎用のコンフィギュレーションAPIとして公開しているその名もConfigというライブラリがある(キャメルではなくローワーケースが正式名称かも知れない)。

設定ファイルのフォーマットは.propertiesファイルと.jsonファイル、そしてHOCONと呼ばれるフォーマットで記述された.confファイル。最後にファイルとはちがうが設定情報の読み込み元としてシステム・プロパティが加わる。

使い方はいたって簡単。まずはライブラリのjarを入手してクラスパスに配置する。ビルドにMavenを使用している場合はpom.xmldependenciesに以下の依存性を追加する(ちなみに少なくとも最新版はJava8でコンパイルされていた README.mdによれば現在最新バージョンはJava8向けに開発・メンテされているとのこと。そしてJava6で使用したい場合はバージョン1.2.1を使用すべしとのことである。2015/08/18追記):

<dependency>
	<groupId>com.typesafe</groupId>
	<artifactId>config</artifactId>
	<version>1.3.0</version>
</dependency>

そしてJava(やもちろんScalaでも)のコードでは以下のようにファクトリーを通じてConfigインターフェース実装のインスタンスを得る:

final Config config = ConfigFactory.load();


あとはキーを指定して設定ファイルに記載してある(してあるべき)情報を取得するだけである。設定ファイルが次のような内容であるとすれば:

{
    "sample" : {
        "foo" : "hello",
        "bar" : [123, 456, 789],
        "baz" : true
    }
}


プログラム側は次のようなかんじでその設定情報にアクセスできる:

// キーはドット区切りで記述する。ようするにJSONのプロパティ・ツリー:
final String foo = config.getString("sample.foo");
// JSONの各種データ型に対応したメソッドがある。次のコードは配列の例:
final List<Integer> bar = config.getIntList("sample.bar");
// getConfigメソッドで順々に階層を下って行くこともできる:
final boolean baz = config.getConfig("sample").getInt("baz");


ConfigFactory.load()にはオーバーロードがいくつも用意されているが、引数なしのものは特別。まずこのメソッドにより設定情報をロードしてConfigインスタンスを初期化する場合、以下の設定情報が読み込まれる(優先度の高い順に並べている):

  • システム・プロパティ
  • application.conf − クラスパス上にあるこの名前のすべてのリソース。
  • application.json − 同上。
  • application.properties − 同上。
  • reference.conf − 同上。


例えばreference.confapplication.propertiesに同じキーの項目が定義されていた場合は後者の値が採用される。またreference.confapplication.propertiesに異なるキーで項目が定義されていた場合はいずれの値にもプログラム側からアクセスできる。

さらに任意の設定ファイルをロードさせたい場合、以下のシステム・プロパティを使う方法が提供されている:

  • config.resource − クラスパス上に存在するファイルを拡張子を含むファイル名で指定。つまりapplicationではなく、application.confConfigFactory.load()オーバーロードでは設定ファイル名を指定する場合そのベース名だけで指定するのだが、それとは形式が異なるということ。
  • config.file − ファイルシステム上に存在するファイルをパスで指定。こちらも拡張子を含む。
  • config.url − URLで指定。

この方法で任意の設定ファイルのロードを矯正できるのはアプリケーション側で引数なしのConfigFactory.load()を使っている場合だけである点に注意する必要がある。

ちなみにHOCONはJSONを拡張したスーパーセットで、JSONフォーマットの冗長さを取り除いて、さらにいくつかの便利機能を提供してくれるもの。見た感じYAMLとくらべて大幅に可読性に優れている(曖昧性が少ない)。ただ「あえてここで新フォーマットに手を出す」理由が見つけられないので今回は学習をスキップ。