DIコンテナ その5 Seasar2編

の続き。

今回はインジェクションタイプであげた4種類のうちの最後のSeasar2


いつものインターフェース。アノテーションはついていません。

package seasar2test;

public interface Hello {
    String getMessage(String name);
}


実装。アノテーションはついていません。

package seasar2test;

public class HelloImpl implements Hello{

    public String getMessage(String name) {
        return "はろー"+name+"さん";
    }

}


設定ファイル。ちょっと分かりにくいですが、NewMainとImplで終わるクラス名を自動登録するという仕組みです。Seasar2はデフォルトの動作がpublicなフィールドやセッター等があると勝手にインジェクトされてしまうため、非常に扱いが難しいです。そのため、注入箇所を明示する必要がある「SEMIAUTO」指定は個人的に必須だと思われます。動作の根本にかかわる部分を勝手にやってくれるというのは非常に危険だと思われます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>

    <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister" >
        <initMethod name="addClassPattern">
            <arg>"seasar2test"</arg>
            <arg>".*Impl,NewMain"</arg>
        </initMethod>
        <property name="autoBindingDef">@org.seasar.framework.container.assembler.AutoBindingDefFactory@SEMIAUTO</property>
    </component>

</components>


動かしてみます。注入箇所にアノテーションを使っています。おかげでどの部分がDIコンテナによって使用されるのかがはっきりとわかるようになるので、他人のソースを後から見る場合や時間がたった後見直す場合に有効だと思われます。

package seasar2test;

import 省略

public class NewMain {

    @Binding
    Hello hello;

    public void print(){
        System.out.println( hello.getMessage("Seasar2") );
    }

    public static void main(String[] args) {
        SingletonS2ContainerFactory.setConfigPath("seasar2test/config.xml");
        SingletonS2ContainerFactory.init();
        S2Container container = SingletonS2ContainerFactory.getContainer();

        NewMain main = (NewMain) container.getComponent(NewMain.class);
        main.print();
    }

}


ちなみにこの場合クラスで呼び出していますが、デフォルトの状態ではパッケージ名を削除し、最後の「Impl」という部分の削除、先頭の文字を小文字にするという変換が行われて登録されているため、文字列での取得も以下のように可能です。

        NewMain main = (NewMain) container.getComponent("newMain");


今回のサンプルではGuiceEJBSpring Frameworkではインターフェースから実装のクラスを探しいくような動きだったのに対して、Seasar2はあくまでも実装をどのような名前で登録するか、といったSpring1.x時代の登録の仕方となっています(同様の実装の仕方がわからなかったので詳しい人意見ください)。結果、自動登録をする場合名前がぶつかっていなければ大丈夫なようですので、ひとつのインターフェースに複数の実態が登録されていても文句を言われないのは、4種類のサンプルの中で今回のSeasar2のサンプルだけとなっています。GuiceやSpringも同一のことは出来ますが、EJB3は基本的に無理だと思ってください。


見て分かるとおり、一番シンプルな扱い方をしたつもりですが、それでもSeasar2は正直使いこなすための敷居が最も高いDIコンテナです。そのかわり開発者が日本人なだけあって日本語で質問をすることができるのはメリットだと思います。


気になってるのは今回あげた4つのDIコンテナの中で今後のロードマップが唯一たっていないのがSeasar2だったりします。

環境構築するときに別途ダウンロードが必要なS2Tigerを毎回忘れる上に、コンテナ本体とバージョンを合わせる必要があるのでこのへんが解決されたりするとうれしいと思います。本体もenum等を使うようにしたりJ2SE 5.0以上を前提にしてわかりやすいインターフェースにしてS2Tiger部分を同一に収めてSeasar2 2.5とか出ると便利じゃないかなーとか勝手に思ってたり。

EJBが便利さを残しつつどんどんシンプルになってることや、SpringやGuiceのシンプルな記述も可能なところと比べると、Seasar2は小難しいところが多い初期のSpringみたいなものが残っていて、もっとシンプルにして機能減らしてSeasar2 liteとかあってもいいんじゃないかなとも思ったり。思わなかったり。