DIの設定ファイルで外部ファイル(プロパティファイル)を参照するには? | Java Springの逆引きメモ

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

テーマ:

ここでは、Springの設定ファイルで外部ファイル(プロパティファイル)を参照する方法を書いてみます。

え!?わざわざ外部のファイルをみなくてもそのままSpringの設定ファイルに書けばいいじゃない、と

思った方は下の「前座」を読んでみてください。



【前座】

Springの設定ファイルでクラスの初期値も設定できます。

これの便利なところは、わざわざ外部定義読み込みようの機能を実装しなくても、設定を外部定義できるところです!


しかし、WEBなどではSpringのファイルはwarの中に入れなければなりません。

これは少し問題です。

環境が複数あり、環境ごとにDBの接続先のID/PWが違う場合はどうしましましょうか?

Mavenの機能で環境ごとに接続先を書き換えるようにすればだいぶ解決しますが、

お客さんが「ベンダーには運用機のDBのID/PWは教えたくない!」といわれたらどうします?

お客さんに「Springの設定ファイルをいじってwarファイルを作リ直して!」、といいます?


そうなんです。

Springに設定を書くととても楽なのですが、環境ごとに設定を変えたい場合は、外部参照ファイルをwarファイルとは別に作成して利用できると解決できることが多そうです!

いろいろな立場の人物が介入するような場合は特にですね。



【サンプル】

<applicationContext.xml>

※beansタグは省略しています。他の記事を参照してみてください。


<bean id="dbPlaceConf" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:D:/test.properties"/>
</bean>


<!-- Data Source -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>



<test.propertiesファイル(外部参照ファイル)>

db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost/test?useUnicode=true&characterEncoding=utf-8
db.username=postgres
db.password=postgres




【説明】

PropertyPlaceholderConfigurerというSpringのクラスを使用すると、${}の形でプロパティファイル内の値を参照することができます。

ですので、上記のDataSourceのようにキーワードで記述すれば外部ファイルに記述した値が埋め込まれます。

便利ですよね。

サーバごとにこのプロパティファイルを変えれは、tomcatでデプロイするwarファイルをサーバごとに作り直す必要がなくなります。ニコニコ

楽ですね!


 ※一応、locationプロパティについて補足しておきましょうか。

  これはSpringのResouceインタフェースになっています。

  文字列を設定できるのは、Springが自動で変換してくれているからです。

  この変換はなかなか面白いです。

  上記では、「file:」を先頭に記述していますが、実は書かなくてもファイルパスは書けます。

  しかし、WEB-INFをルートとしてそこからの絶対パス、または相対パスとなるため、

  warの外に外部ファイルを置きたいという目的に合いません。

  今回のようにシステムの絶対パスを指定したい場合は、「file:」という接頭語をつけるとSpringが

  変換してくれます!

  他にも、「classpath:」という接頭語もあるようです。

  このあたりをうまく使って、いろいろ自由に設定をしてみましょう。

  自作のクラスのsetterの引数にResouceを使用してファイルを取得するのも柔軟性が高くなって

  面白そうですねー。



<環境変数またはシステムプロパティを使用する場合>

環境変数を使用できると、1つのサーバ内で複数の環境を構築する場合も楽になります。

実は環境変数やシステムプロパティ も${}で参照します!


例えばWindowsXPの場合、USERNAMEという変数があり、ログインしているユーザIDが参照できます。

これを使った例を見てみましょう。


<bean id="dbPlaceConf" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:C:/Documents and Settings/${USERNAME}/test.properties"/>

</bean>


これだけです!

これは、上記のPropertyPlaceholderConfigurerの設定上だけではなく、すべてのbeanの設定でも同じです。


さて、すると問題が出てきます。

プロパティファイルに記述したキーワードと、環境変数の名前がかぶった場合はどうなるんでしょう?


実は、これも設定できるのです。

PropertyPlaceholderConfigurerのbeanタグ内で以下を設定します。


<property name="searchSystemEnvironment" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>



1行目は、環境変数を使用するかどうか?を設定します。(デフォルトtrue)

2行目は、環境変数とプロパティファイルのどちらを優先にするか?を設定します。

使用できる設定は以下のとおりです。

設定値 意味
SYSTEM_PROPERTIES_MODE_FALLBACK

プロパティファイルにキーワードが見つからないとき、環境変数またはシステムプロパティを探しに行きます。

デフォルト値です。

SYSTEM_PROPERTIES_MODE_NEVER 環境変数およびシステムプロパティは一切参照しません。
SYSTEM_PROPERTIES_MODE_OVERRIDE 環境変数およびシステムプロパティの設定を優先します。





参考:

・トップ

・DIの設定ファイルを書くには?

・DIの設定ファイル内から外部DIファイルを参照するには?

・プロパティファイルをPropertiesクラスのbeanにするには?

・システムプロパティとは?