[Seasar-user:722] Re: instance="prototype" にはまった私
B rmail.plala.or.jp suga
suga_k
2004年 5月 1日 (土) 01:23:07 JST
スガです。
勉強がてらに追いかけてみました。
On Fri, 30 Apr 2004 20:45:44 +0900
jazzatny <[E-MAIL ADDRESS DELETED]> wrote:
> 2)次に、MaximDisplayの引数なしコンストラクタのコメント
> をはずし実行すると、
> java.lang.NullPointerException
> at test.seasar.MaximDisplay.setMaximStr
> (MaximDisplay.java:17)
> とExceptionをはきます。これはmaxim.xmlに
> autoBinding="constructor"もしくは"auto"を
> 設定しても同様です。
ここは prototype かどうかは関係なく、
org.seasar.framework.container.assembler.
AutoConstructorAssembler#getSuitableConstructor()
の中で明示的に
if (tempArgSize == 0) {
return null;
}
としていますので、ドキュメントの間違いではないかと思います。
# ちなみに上の三行を削れば引数有りを優先します。
少なくとも現状では、引数無しのコンストラクタがある場合、必ず
引数無しのコンストラクタが使われます。
autoBinding="constructor" だと初期化はそこで終わります。
"auto", "property" だと引き続き property による初期化が実行されます。
なお当然ながら、このとき xml で
<component name="display" instance="prototype" class="MaximDisplay">
<property name="maxim">maxim</property>
</component>
とし、setter
MaximDisplay#setMaxim(IMaxim maxim) {
maxim_ = maxim;
}
を作る必要があります。
---------------------------------------------------------------
> 3)更に、maxim.xmlのコンポーネントname="display"に
> <arg>maxim</arg>を設定し実行すると、
> ++ しています。
> ++ しています。
> ++ しています。
> と出力されます。これもmaxim.xmlに
> autoBinding="constructor"、"auto"を設定しても同様です。
これは Sel を使った場合のみの現象で、バグっぽいです。
# XML でのコンポーネント指定 = Sel を使う
org.seasar.framework.container.impl.ArgDefImpl#getValue()
if (childComponentDef_ != null) {
return childComponentDef_.getComponent();
}
if (value_ != null) {
return value_;
}
if (expression_ != null) {
Expression exp = new SelParser(expression_).parseExpression();
setValue(exp.evaluateValue(container_.getSelContext())); //-- (1)
//** ここで getComponent() の結果をセットしてしまっているため、
//** 次以降は生成されずに同じ物がセットされる。
//** singleton ならこれで問題ない。
}
return value_;
(1) の行の内部処理はここ
org.seasar.framework.container.impl.
S2ContainerSelContext#getVariable(String name)
if ("this".equals(name)) {
return this_;
} else {
return container_.getComponent(name);
}
XML の display 設定部分を抜き出すと
<component name="display" instance="prototype" class="MaximDisplay">
<arg>maxim</arg>
</component>
この設定を Java コードで行うとこのようになるでしょう。
ComponentDefImpl cd = new ComponentDefImpl(MaximDisplay.class, "display");
cd.setInstanceMode(ComponentDefImpl.INSTANCE_PROTOTYPE);
ArgDefImpl argDef = new ArgDefImpl();
argDef.setExpression("maxim"); //-- (2)
cd.addArgDef(argDef);
container.register(cd);
(2) の部分は、現状では実質下記と同じ動作をします。
argDef.setValue(container.getComponent("maxim"));
で、意図した動作をするのはこうではないでしょうか。
argDef.setChildComponentDef(container.getComponentDef("maxim"));
--------------------------------------------------------------
e-mail: [E-MAIL ADDRESS DELETED]
スガ
--------------------------------------------------------------
Seasar-user メーリングリストの案内