選択系コンポーネントのDI

前回書いたように、選択系アイテムの中身(選択肢)は描画毎に生成するのはどうも効率が悪い。もちろん状況に応じて選択肢が変わるような場合は別だが、例えば都道府県の選択などはどの画面でもどの状況でも変わらないと思われる。だったら完成品をDIしてもらうのがいいのではないか。

方法1(手作り)

せっかく前回ひがさんからコメント頂いたのでMapを使う方法でやってみます。

<component name="prefectureItems" class="java.util.ArrayList">
    <initMethod name="add" >
        <arg>
            #{"value" : "01", "label" : "北海道"}
        </arg>
    </initMethod>

        ・・・・

    <initMethod name="add" >
        <arg>
            #{"value" : "47", "label" : "沖縄県"}
        </arg>
    </initMethod>
</component>

一応これでできるはずですが、やる人・・・いないですよね。

方法2(マスタから取得)

  • 都道府県リストをマスタから取得し保持するList実装を作る。(PrefectureItemsクラス)
  • 上記をdiconに登録する。
<component name="prefectureItems" class="hoge.fuga.PrefectureItems">
  • PageクラスにprefectureItemsというプロパティとprefectureというプロパティ、HTMLにid="prefecture"のラジオ/プルダウン等

方法3(2の応用編〜コンテナへ自動登録〜)

どうせならdiconに書かなくても自動登録したい!という訳で挑戦。
PrefectureItemsをPrefectureDtoにしてdtoパッケージへ。これでできると思いきやできない。
そもそもprefectureItemsがnull、つまりDIされてきていないようなので原因を調査。

  • そもそもdtoはDIされないのではないか?

⇒SomeDtoというString型のプロパティ1つだけのクラスを作成したところDIされてきた。

  • ではArrayListを継承したのがまずかったか?

⇒SomeDtoもArrayListを継承させてみたがDIされてきた。

  • もしやと思いprefectureItemsをprefectureDtoへリネーム

⇒き、きた!!
どうやらプロパティ名はクラス名の先頭を小文字にしたものでないとDIされてこないみたいです。
これ、個人的にはすごく衝撃的だったんですが、こんな規約どこかに書いてありましたっけ??未だに半信半疑なので今度ソースを覗いてみようと思います。
それはさておき、そうなると〜Itemsというクラスを自動登録するようにしなきゃダメってことですよねきっと。
たぶんcreatorを作ればいいんだと思うんだけど・・・。

public class ItemsCreator extends ComponentCreatorImpl {
    public ItemsCreator(NamingConvention namingConvention) {
        super(namingConvention);
        setNameSuffix("Items");
        setInstanceDef(InstanceDefFactory.PROTOTYPE);
        setEnableInterface(true);
        setEnableAbstract(true);
    }
}

既存のCreatorをパクって作成してみました。カスタマイザーはよくわからないので省いちゃいましたが。。。
creator.diconにこのクラスを加えたら見事DIされるようになりました!