Javaで設定ファイルというと、propertiesファイルを使うのが一般的かと思いますが、key=value形式だけしか使えなかったり、
テスト環境や本番環境でほんの一部だけ値を切り替えたい場合でも、ほとんど同じファイルを環境の数だけ作らないといけなかったりと、結構面倒です。
Play Frameworkでも使っている、「Typesafe Config」というライブラリを使うと、これらの問題が解決できるようでしたので、まとめてみました。
一応Githubにもコミットしてあります。地味にGit初めて使いました。
https://github.com/2KB/config-test01
#Typesafe Configとは
・Java製のコンフィグファイルを使用するためのライブラリ。
・Scalaの創始者が立ち上げた、Typesafe社が作っている。
・jarファイルを一個読み込むだけで簡単に使える。
・Jsonライクな記載ができ、表現力が高い。(HOCONとかいう形式らしい)
#Typesafe Configで何ができるか
・単なる key value 形式だけでなく、JSONのように、配列やオブジェクト形式で値が定義できる。
・一度定義した値の使い回しや、環境変数などもつかえる
・一部だけ設定を変えた、環境ごとの設定ファイルを簡単に作れる
#使い方
##Jar追加
まずはJarを追加します。
Mavenなら
<dependencies>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
のように記載します。
直接ダウンロードしたいときは下記からとってきましょう。
http://mvnrepository.com/artifact/com.typesafe/config
##コンフィグファイルの用意
クラスパスが通っているところへ、コンフィグファイルを用意します。
デフォルトだと application.conf というファイル名にします。
今回は以下のように記載してみます。
// 文字設定。利用可能な値の型は string、number、object、array、boolean、null
word1 = "application.confです"
// 配列1
array1 = [1, 2, 3]
// オブジェクト1
object1 : {
bar : 10,
baz : 12
}
// オブジェクト2。こう書いてもよい。
object2.bar=10
object2.baz=12
// 値を使い回す。環境変数も使える
standard-timeout = 10ms
foo.timeout = ${standard-timeout}
// 値の上書き
// PATH という値がない場合は単に無かった事にされます。しかし、PATH という環境変数が設定されている場合は、環境変数の方が利用されます。
env.path = /default/path
env.path = ${?PATH}
コメントで記載したように、配列はオブジェクトなど、色々な形式で記載できます。
また、環境変数なども使えます。
##値取得
Config config = ConfigFactory.load();
として、上記で作成したコンフィグ値を取得します。
import java.util.List;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigObject;
public class TypesafeConfigTestMain {
public static void main(String args[]) {
// コンフィグのパスがシステム設定値にあるか確認。ここに指定がなければ、「application.conf」を使用する
String configResource = System.getProperty("config.resource");
System.out.println("configResource : " + configResource);
// コンフィグを取得する(load(ファイルパス)とすることで、手動でパスを指定することも出来る)
Config config = ConfigFactory.load();
// 文字取得
String word1 = config.getString("word1");
System.out.println("word1 : " + word1);
// 配列取得
List<Integer> array1 = config.getIntList("array1");
System.out.println("array1 : " + array1);
// オブジェクト取得
ConfigObject object1 = config.getObject("object1");
System.out.println("object1 : " + object1);
// 値の使い回し結果取得
String timeout = config.getString("foo.timeout");
System.out.println("timeout : " + timeout);
// 環境変数結果取得
String path = config.getString("env.path");
System.out.println("env.path : " + path);
}
}
実行すると、作成したコンフィグ値が取得出来たはずです。
##環境ごとに一部値を切り替えたファイルを使う
一部だけ値を変えて、別環境用のファイルをつくる、ということはよくやると思います。
そこで、word1の値だけを変えた、別環境用のファイルを作ってみます。
// 基本値はすべて application.confから取得する
include "application.conf"
// 値を上書き
word1 = "application-test.confです"
ポイントは、「include "application.conf"」の部分です。
このように、基本的な値を別のコンフィグファイルから取得することができるので、
差分があるものだけを上書きするだけで、環境ごとのコンフィグファイルが作れます。
そしてこのコンフィグは、VMの環境変数、「config.resource」などの値で切り替えることができます。
Java実行時に、引数で渡してやると便利です。
例えば maven package などで jar化して、実行する場合
java -classpath config-test01-0.0.1-SNAPSHOT-jar-with-dependencies.jar com.github.kb2.mains.TypesafeConfigTestMain
出力結果:
word1 : application.confです
java -Dconfig.resource=application-test.conf -classpath config-test01-0.0.1-SNAPSHOT-jar-with-dependencies.jar com.github.kb2.mains.TypesafeConfigTestMain
出力結果:
word1 : application-test.confです
このように、「-Dconfig.resource=application-test.conf」などと設定値を渡してやることで、使用するコンフィグファイルを切り替えることが出来ます。
上記のJarは、Githubにあるソースから、maven package すると、作成できます。
Eclipseから実行する際は、「Run Configuration」項目で、「Arguments」の「VM Arguments」に
「-Dconfig.resource=application-test.conf」
と設定して実行するといいでしょう。
ちなみに、-Dconfig.resource はクラスパスからコンフィグを探しますが、 -Dconfig.file をかわりに使うと、ファイルパス上からコンフィグを探すそうです。
#参考
公式:
https://github.com/typesafehub/config
https://github.com/typesafehub/config/blob/master/HOCON.md
Play Frameworkのドキュメント:
http://www.playframework-ja.org/documentation/2.1.5/Configuration
Qiita:
http://qiita.com/FumiyasuSumiya/items/89da99006d6d2fec805e