Grails 2ではGrails自身が実装していた設定ファイルの外部化は、Grails 3ではSpring Bootにまかされることになりました。
本記事では、Grails 2までの設定ファイル外部化となるべく似たような動作をするようにGrails 3設定してみます。
やることは、Applicationクラス(grails-app/init/hoge/Application.groovy)に以下のようにアノテーションを付与することだけです。
import org.springframework.context.annotation.*
@PropertySources([
@PropertySource(value="classpath:hoge.properties"),
@PropertySource(value="file:///opt/hoge/conf/hoge.properties", ignoreResourceNotFound = true),
@PropertySource(value='file:///${hoge.conf.file}', ignoreResourceNotFound = true)
])
class Application extends GrailsAutoConfiguration {
static void main(String[] args) {
:
上記によって以下のように動作します。
- (1) warファイルやクラスパス中のhoge.properties(ソースコードとしてはsrc/main/resouces/hoge.propertiesに置く)を読み込む。このファイル中には設定のデフォルト値を記入しておく。
- (2) もしファイル「file:///opt/hoge/conf/hoge.properties」があれば設定ファイルとしてそれを読み込む。(1)で設定されたプロパティで同名のものは上書きされる。なければ何もしない。
- (3) もし、システムプロパティ「hoge.conf.file」もしくは環境変数「HOGE_CONF_FILE」で指定されたファイル名のファイルががあればそれを読み込む。(1)(2)で設定されたプロパティで同名のものは上書きされる。なければ何もしない。
run-app時、およびwar化してtomcatにデプロイしても同様に動作します。
ちなみに上記はSpring Bootの機能というだけです。(→参考)
余談
Spring Boot標準の設定ファイルの外部化の説明はこちらにありますが、非常に高機能かつ汎用的です。Spring Bootの主たる設定ファイルapplication.yaml(application.properties)は、特に何も設定しなくてもシステムプロパティspring.config.location(もしくは環境変数SPRING_CONFIG_LOCATION、etc)で切り替えることができます。その場合、Profile-specific application propertiesというものに応じてファイル名を選択する、なども可能です。(Seasar2の「暗黙的な条件インクルード」と似た機能)
ただ、spring.config.location方式だと、ベース名(デフォルトでappliction.yamlの「application」)を変更したい場合については、別のシステムプロパティ(spring.config.name)などの設定が必要になり、その設定は設定ファイルに書けない以上、環境変数やシステムプロパティで指定するしかなく、「環境変数やシステムプロパティを指定しない」ときにapplicationから読み込もうとしてしまう、という問題があり、Grails 2までの動作と上手く整合する方法をみつけられませんでした。
もし、外部化する設定ファイルのファイル名がapplication.yaml(.properties)のままで良いのであれば、あるいはシステムプロパティや環境変数の設定が必須であるような運用ルールとするならば、spring.config.locationを使う方式でも良いかもしれません。その場合、特に設定はいりません。