Re: Statelessのinstance属性

微妙...
単純に singleton にマッピングだと,今度は (というか元に戻って) 「4.7.11 Non-reentrant Instances」を満たすことができません.

The container must ensure that only one thread can be executing an instance at any time.

セッションビーンは再入不可であり,スレッドセーフに作る必要がありません.
やはりスレッドセーフであることが保証されない EntityManager を安心して使えるのも,セッションビーンが再入不可だからです.
そんなわけで (どんなわけで?),SLSB を singleton にマッピングするのはまずいです.
SynchInterceptor を使えば singleton でも再入不可にできますが,これは性能面でのペナルティが大きくて問題あり.
といってやたらと javax.ejb.ConcurrentAccessException を吹っ飛ばすのもいかがなものか.
結局,prototype にマッピングするしかないと思います.


じゃあ「3.4.5.2 Stateless Session Beans」をどうするかというと,ちゃんとサポートするならセッションビーンインスタンスとクライアントが持つ参照は別にするべきかと.
要するにクライアントはプロキシを参照するということですね.たとえローカルでも.
そしてプロキシの equals() は「3.4.5.2 Stateless Session Beans」の通りに振る舞うけれども,その背後にあるセッションビーンインスタンスはメソッド呼出しの都度違っているかもしれない,みたいな.
つまり,プロキシは singleton,セッションビーン本体は prototype.


たぶん,まっとうな EJB コンテナはそうなってると思うのですが,お手軽サポートでいくなら SLSB の equals() をオーバーライドして (あるいは AOP 使って) ComponentDef の同一性をチェックするようにするという手もありかも.
とりあえず「3.4.5.2 Stateless Session Beans」「4.7.11 Non-reentrant Instances」両方を満たせるはず.
あ,SLSB が複数のビジネスインタフェースを持ってる場合に,型が異なる参照は equalsfalse を返さなきゃいけないのに対応できないか (これは singleton の場合も同じ問題あり).


やっぱりプロキシでのサポートが必要なような...
例えば PrototypeDelegateInteceptor を使って,

<component class="Foo">
  <aspect>
    <component class="PrototypeDelegateInterceptor">
      <property name="targetName">fooBean</property>
    </component>
  </aspect>
</component>

<component name="fooBean" class="FooBean" instance="prototype"/>

みたいな状況を作ってあげればよさげ.
んで,@EJB に対しては FooBean ではなく,Foo の方を設定.
まぁ,実際にはこんなに簡単にはいかないと思いますが,方向はこうじゃないかなぁ.