S2Configとは?
主なクラスおよびリソース
- 設定情報
設定値をハッシュのようにキーと値の組で管理している情報. - 設定ファイル
設定情報を保持したファイル.デフォルト実装ではプロパティファイルになります. - コンフィグコンテナクラス
設定情報を扱うコンテナクラス. - コンフィグクラス
設定情報をJavaBeansで保持するクラス .
コンフィグコンテナクラスの使い方
コンフィグコンテナは設定ファイルから設定情報を読み込んだり書き込んだりできます. まず,設定情報1つに対して1つのコンフィグコンテナを定義します .configNameは設定名です. デフォルトのConfigPropertiesReaderとConfigPropertiesWriterを利用した場合は 設定名.propertiesという設定ファイルに対応するようになります. また,initMethodでloadToBeansメソッドを指定すると初期化時に読み込んだ設定情報を対応するコンフィグクラスに設定値をDIします.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <include path="s2config-core.dicon"/> <component name="configContainer" class="org.seasar.config.core.container.impl.ConfigContainerImpl"> <property name="configName">"log4j"</property> <initMethod name="loadToBeans"/> </component>コンフィグコンテナは設定値を扱うコンテナですので,以下のようにgetConfigValueメソッドで設定値を取得することができます.
この場合はConfigContainerを使って能動的に設定情報にアクセスすることになりますが,後述するコンフィグクラスでは受動的に設定情報をDIすることが可能になります.
public class HogeAction { public ConfigContainer configContainer; @Execute(validator=false) public String doAction(){ // snip String rootLogger = configContainer.getConfigValue(String.class, "log4j.rootLogger"); // snip } }また,以下のようにすることで既存のdiconファイルに関連づけも可能です.
まず,config.diconを用意します.
ConfigContainerはJava5のジェネリクスに対応したインターフェイスであるため,diconに対応したStrictConfigContainerクラスでラップします.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <include path="s2config-core.dicon"/> <component name="configContainer" class="org.seasar.config.core.container.impl.StrictConfigContainer"> <arg> <component class="org.seasar.config.core.container.impl.ConfigContainerImpl" autoBinding="none"/> </arg> <property name="configName">"hogeSystemConfig"</property> </component> </components>jdbc.diconでconfig.diconをインクルードします.
コンポーネントのプロパティに対してコンフィグコンテナが保持している設定値をDIしたい場合はgetConfigXXXXメソッドを使います.XXXは設定値の型名になります.
getConfigStringメソッドの場合は,第一引数に設定値のキー,第二引数はデフォルト値です.
プロパティファイルなどの設定情報が読み取れない場合は,自動的にデフォルト値がDIされます.プロパティファイルが存在し対象の設定値がある場合はその値でDIされます.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <include path="config.dicon"/> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> <property name="driverClassName"> configContainer.getConfigString("jdbc.driverClassName", "oracle.jdbc.driver.OracleDriver") </property> <property name="URL"> configContainer.getConfigString("jdbc.URL", "jdbc:oracle:thin:@192.168.1.1:1521:BTS") </property> <property name="user">configContainer.getConfigString("jdbc.user", "BTS_REAL")</property> <property name="password">configContainer.getConfigString("jdbc.password", "hogehoge")</property> </component>
コンフィグクラスの使い方
コンフィグクラスはクラスのサフィックスがConfigであるJavaBeansです.(publicフィールドに対応しています)
推奨のサフィックスはConfigですが、Dtoもコンフィグクラスとして扱うことが可能です.
コンフィグクラスとして扱うには以下の条件が必須となります.
- コンフィグクラスに対してConfigアノテーションで設定情報と関連付けを行う.
- コンフィグプロパティに対してConfigKeyアノテーションで設定値と関連付けを行う.
ConfigKeyのreadOnly属性がtrueの場合はコンフィグクラスから設定情報への同期は行われず,readOnly属性がfalseの場合は同期が可能になります.
ConfigKeyアノテーションがないプロパティに対してはプロパティ名で自動的に解決します.
関連づけを強制的に除外したい場合はConfigIgnoreアノテーションを利用します.
@Config(name = "log4j") public Log4jConfig{ /** log4j.rootLogger と読み込み専用で関連づけられます */ @ConfigKey(name = "log4j.rootLogger", readOnly = true) public String rootLogger; /** log4j.category.org.seasar と読み書きできるように関連づけられます */ @ConfigKey(name = "log4j.category.org.seasar") public String categoryOrgSeasar; /** ConfigKeyアノテーションがない場合はプロパティ名で自動的に関連づけられます */ public String key1; /** S2Configとは無関係なプロパティ */ @ConfigIgnore public String ignore; }このコンフィグクラスをウェブアプリケーションなどで使いたい場合は,PageクラスやActionクラスのプロパティに保持するだけでSeasar2によって自動的にDIされるようになります.
public class HogePage { /** log4j.propertiesの情報が読み込まれたコンフィグクラスがDIされます */ public Log4jConfig log4jConfig; }また,デフォルト実装のConfigPropertiesReaderとConfigPropertiesWriterはクラスパス上からプロパティファイルを検索しますので,xxx.propertiesをアプリケーション外に配置すれば外部設定ファイルを扱えるようになります. Tomcat5.5の場合は$CATALINA_HOME/common/classese
環境依存に対応した設定情報の扱い方
設定情報の中でenvキーを使うことによって環境に依存した設定値を扱うことができます.
systemConfig.propertiesで以下のように本番環境のJDBC接続情報を定義しているとします.
envキーを使って環境名をstaingとしています.
systemConfig.properties
env = staging jdbc.URL = jdbc:oracle:thin:@read-db:1521:BTS jdbc.user = BTS_REAL jdbc.password = hogehoge同様にクラスパス上にsystemConfig_staging.propertiesを配置し以下のように定義します.
jdbc.URL = jdbc:oracle:thin:@stagin-db:1521:BTS jdbc.user = BTS_STAGINGこのように定義した場合,jdbc.URL, jdbc.userはsystemConfig_staging.propertiesによって上書きされます.
ただし,jdbc.passwordのようにsystemConfig_staging.propertiesで定義されていない項目については上書きされません.
systemConfigのConfigContainer内部ではsystemConfig_staging用のConfigContainerが子供のコンテナとして生成されます.
コンフィグクラスのプロパティを設定ファイルに同期するには
設定ファイルから設定情報を読み込み,対応するコンフィグクラスにDIするにはloadToBeansメソッドを使います.
逆にコンフィグクラスからコンフィグコンテナ内部の設定情報を上書きする際はsaveFromBeansを呼び出します.この時点では設定ファイルには同期されません.
ConfigKeyアノテーション(name = "log4j.rootLogger", readOnly = true)や,ConfigIgnoreアノテーションがsaveFromBeansメソッドを実行しても無視されます.
同期するにはsyncメソッドを呼び出します.
configContainer.saveFormBeans(); configContainer.sync();ただし,現状の実装では,前述のenvキーを使って環境依存な設定ファイルを保持している場合は,saveFromBeansメソッドを呼び出した場合は,envキーを定義しているルートのコンフィグコンテナに,子供のコンテナから読み込んだ設定値が上書きされてしまいます. 前述の例でいうと, systemConfig_staging.propertiesのjdbc.URLやjdbc.userの値でsystemConfig.propertiesのjdbc.URLやjdbc.userの値を上書きしてしまいます. これは,そのままsyncメソッドを実行してしまうと問題が生じる可能性がありますので,注意してください. 今後の実装では,envキーを使った場合でも対応するコンフィグコンテナ(設定ファイル)に書き戻せるようにする予定です.