佐藤です。

先週に引き続き、Seasar2環境でのあれこれについて。


いろんな案件をこなすたび、毎回思うのが
設定ファイルをXMLにしようか、iniファイル形式にしようか、、、
というあたり。
といっても最近は殆どXMLで、Digesterで読んでたんですが。


Seasar2で開発するにあたって「設定ファイル周りもなんとか簡単にできないもんかな」と思いまして、いろいろ調べていました。

こちらにて
 XML内に[文字列] [数値] [Map] [List]を区別して書くことができ、
 [Map]や[List]をネストさせることも可能なDigesterの使い方

が乗っていたので、それを参考にしまして、階層的な設定もすんなり書けるXML設定ファイルができました。
これで、毎回XMLをどう書くかを気にしなくて良いです。

ただ、これだけだと単に「器用な設定ファイル」が出来ただけで、Seasarとは関係ない。

というわけで、設定ファイルに
  <string key="hoge">設定内容</string>
とか設定されていたら、Tomcat起動時に読み込んでS2Containerに登録しちゃって

 @Resource
 private String hoge;

とかやったら、hogeに"設定内容"がDIされたりするのはどうでしょう?

と思って作ってみました。
これで、設定ファイル用クラス(ConfigUtilとか)を用意して
 ConfigUtil.getString("hoge")
とかやらなくていいのです。
コード内に設定ファイルのキーを示すリテラルが無くなって良い感じです。


実現方法としては、diconファイルに
<component name="initializeService" class="jp.co.ncad.hoge.Init">
    <initMethod name="init"/>
</component>
と言う感じで起動時に実行されるクラスを置いて


public class Init {
    @Resource
    private S2Container container;
   
    private static Digester digester =
        DigesterLoader.createDigester(Configuration.class.getResource(RULE_XML_NAME));


    public void init(){
        Map map = (Map)digester.parse(CONFIG_XML_PATH);

        for (String key : map.keySet()) {
            container.register(new SimpleComponentDef(defaultMap.get(key), key) {
                public AutoBindingDef getAutoBindingDef() {
                    return AutoBindingDefFactory.AUTO;
                }
            });
        }
    }
}

と言う感じ。
SimpleComponentDefの実装を内部クラスでやってるあたり・・・・ちょっと手荒かな?という気もしなくも無いですが、一応実現できました。
他にもっと良い方法があるのかもしれません。

難点は、Tomcat再起動しないと設定ファイル再読込みしない、ということで
再起動せずに毎回設定読むような要望があると対応できないのです。
きっとこれもやり方次第で何とかなるんだろうなと思いますが。

もう少しS2Containerについての知識を深めないといけませんね。。