[seasar-javadoc:177] Re: InstanceDef

O.Goto o-goto @ try-net.or.jp
2006年 6月 4日 (日) 13:57:08 JST


後藤(goto)です。

On Sun, 04 Jun 2006 13:00:14 +0900
Koichi Kobayashi <koichik @ improvement.jp> wrote:

> 小林 (koichik) です.
> 
> > application、request、sessionについては間違っていないですよね?
> > ここでの説明ではsingletonとprototypeについては一切触れていないのですが・・・
> 
> あ,なるほど.
> application, request, session に限定した話だったのですね.
> 最初の一文を見ただけでは限定された話ということが分かりにくいかも.
> 
> > singletonとprototypeはインスタンススコープという概念とは異なりますよね?
> 
> 「スコープ」の捉え方によりますね.
> 可視性的な意味合いだと異なってると感じるのかも.
> ライフサイクル的な意味合いだと異なっていると感じないかも.
> 自分は後者で見てますね.
> 
> > 誤解を招かないようにするにはsingletonとprototypeも説明に含めるしかないですかね?
> > でも先ほども書いたようにsingletonとprototypeにインスタンススコープというのは違和感を感じるのです。
> 
> それでは「インスタンススコープ」をやめましょうか.
> 
> > singletonとprototypeについては私の認識は多分間違っていないと思うのですが、間違っていると問題なので確認です。
> > 
> > singletonにはsingletonとprototypeがインジェクション出来ます。
> 
> S2Container#init() 前にちゃんと ExternalContext が設定されていれば
> (設定すべきですが) application もインジェクションできます.
> 
> > prototypeにはsingleton、prototypeがインジェクション出来ます。
> > (?prototypeにもapplication、request、sessionはインジェクション出来る?自信なし)
> 
> 条件付きですが,インジェクションできます.
> 条件というのは,例えば singleton にインジェクションされる
> prototype などを除く (この場合は application のみ可) こと.
> そうでなければ request,session もインジェクションできます.
> 
> > この時点でapplication、request、sessionで書いたインスタンススコープの説明とは矛盾がでてしまいます。
> > singletonは唯一のインスタンス、prototypeは必要とされる度にインスタンスが生成されるというだけで、
> > それ以上でもそれ以下でもないと思うのです。
> 
> やはり「スコープ」と考えない方がいいかも.
> どのインスタンスモードも,それぞれのコンテキストで最初に
> 「必要とされた時」に,1 回だけインスタンスを生成します.
> それ以上でもそれ以下でもありません.
> 
> そのコンテキストが singleton ならコンテナになるし,prototype なら
> 「必要とされた時」そのものになります (結果的に毎回).
> そして application ならアプリケーションコンテキスト,session なら
> セッションコンテキスト,request ならリクエストコンテキスト毎に
> なります.
> 私は singleton/prototype と application/session/request で
> 大きな違いがあると考えていません.
> # ExternalContext の提供が必要という点を除く
> 
> インジェクションできる/できないというのは,そのインスタンスが
> 生成される時点で存在するコンテキストからはインジェクションできて,
> 存在しないコンテキストからはインジェクションできないということです.
> 
> 例えば session に request をインジェクションすることも可能なのです.
> ただし,session のコンポーネントが生成される時点のリクエスト
> コンテキストで生成されたコンポーネントがインジェクションされます.
> それは,その session のコンポーネントを別のリクエストコンテキストで
> 取得した時の request のコンポーネントとは異なるので,多くの場合は
> 開発者の意図したことと異なるのではないですか,ということです.
> 
> 例で示すと,session のコンポーネント S を最初に取得すると
> その時のリクエストコンテキストから requect のコンポーネント R1 が
> インジェクションされるとします.
> 別のリクエストコンテキストでは,request のコンポーネントは
> R2 になっていますが,その時でも S が参照しているのは R1 であり,
> R2 には変わりません.
> それが開発者の意図したとおりならそれでも問題ないのですが,
> たいていの場合はそうではないでしょう,ということです.
> 
> この話は singleton と prototype に置き換えても同様です.
> ただ,singleton と prototype では,上のようになることが
> 意図したとおりであることが多いので問題になることはあまり
> ないと思いますけど.
> 
> > 一方、application、request、sessionについては必要とされる度にインスタンスが生成されるという
> > prototypeの性質とスコープを絞れば唯一のインスタンスというsingletonの性質の2つを兼ね備えていると思うのですが、
> > これって間違っています?
> 
> そんなわけで (どんなわけで?),こういう風には考えていません.
> 
> > インスタンスの格納先がそれぞれapplication、request、sessionになるわけですよね。
> 
> 手段としてはそうですね.
> 
> > applicationにはapplication、singleton、prototypeがインジェクション出来ます。
> > sessionにはsession、application、singleton、prototypeがインジェクション出来ます。
> > requestにはrequest、session、application、singleton、prototypeがインジェクション出来ます。
> > 
> > これも間違っていないですよね?
> 
> application に singleton や prototype は少し微妙かも.
> Web アプリケーションでは application は ServletContext に
> 保持されます.
> そして ServletContext というのは Web アプリケーション全体で
> 一つのインスタンスを共有します.
> もし Web アプリケーションが複数の (独立した) S2 コンテナ (階層) を
> 持っている場合,インスタンスモード application のコンポーネントは
> それぞれの S2 コンテナ (階層) で共有されます.
> この場合に singleton のコンポーネントをインジェクションすると
> 開発者が意図した結果とは異なるかもしれません.
> 
> 実際には,SingletonS2ContainerFactory で生成した一つの
> S2 コンテナ (階層) を,Web アプリケーション全体で共有するのが
> 普通なので,これを Javadoc に記述する必要はあまりないような気も
> しますが.
> 
> > これらの「〜は〜をインジェクション出来ます、」っていう説明を全て書いてしまえば解決?
> 
> その方が説明しやすければそれでもいいかもしれません.
> 全部で 5 コしかないので,表あるいはリストを使って読みやすく
> できるならその方が分かりやすいかもしれませんね.
> 


確認してよかったです。大きな勘違いをしているのがわかりました。

> どのインスタンスモードも,それぞれのコンテキストで最初に
> 「必要とされた時」に,1 回だけインスタンスを生成します.
> 
自分の認識として合っていたのはここだけでした(笑)。

> インジェクションできる/できないというのは,そのインスタンスが
> 生成される時点で存在するコンテキストからはインジェクションできて,
> 存在しないコンテキストからはインジェクションできないということです.
> 
これは全てのインスタンスモードについて言えるわけですよね。
ということは、「〜は〜をインジェクション出来ます。」というように単純には表やリストには出来ないですよね。
どうしたら一番いいのかな?


 * <p>
 * コンポーネントのインスタンススコープが自身より短いコンポーネントをインジェクションすることは出来ません。 インスタンススコープの長さは、
 * <code>application</code>&gt;<code>session</code>&gt;<code>request</code>となります。
 * <code>application</code>には、 <code>session</code>と<code>request</code>をインジェクションすることは出来ません。
 * <code>session</code>には、 <code>request</code>をインジェクションすることは出来ません。
 * </p>

この部分はまるまるカットして、

 * コンポーネントインスタンス定義の種類には、以下のものがあります。
 * <dt><code>singleton</code>(default)</dt>
 * <dd>S2コンテナ上で唯一のインスタンスが生成されます。</dd>
 * <dt><code>prototype</code></dt>
 * <dd>コンポーネントが必要とされる度に新たなインスタンスが生成されます。</dd>
 * <dt><code>application</code></dt>
 * <dd>アプリケーションコンテキスト毎に1つのインスタンスが生成されます。</dd>
 * <dt><code>request</code></dt>
 * <dd>アプリケーションコンテナのリクエスト毎に1つのインスタンスが生成されます。</dd>
 * <dt><code>session</code></dt>
 * <dd>アプリケーションコンテナのセッション毎に1つのインスタンスが生成されます。</dd>

これを直して、

 * コンポーネントインスタンス定義の種類には、以下のものがあります。
 * <dt><code>singleton</code>(default)</dt>
 * <dd>S2コンテナ上で唯一のインスタンスになります。</dd>
 * <dt><code>prototype</code></dt>
 * <dd>コンポーネントが必要とされる度に異なるインスタンスになります。</dd>
 * <dt><code>application</code></dt>
 * <dd>アプリケーションコンテナのアプリケーションコンテキスト毎に1つのインスタンスになります。</dd>
 * <dt><code>request</code></dt>
 * <dd>アプリケーションコンテナのリクエストコンテキスト毎に1つのインスタンスになります。</dd>
 * <dt><code>session</code></dt>
 * <dd>アプリケーションコンテナのセッションコンテキスト毎に1つのインスタンスになります。</dd>
 * それぞれ、インスタンスが生成されるタイミングはそのコンポーネントが必要とされる時になります。
 * コンポーネントにインジェクションできるコンポーネントは、インジェクション対象コンポーネントのインスタンスが生成される時点で存在するコンテキストのコンポーネントからのみです。


いまいちわかりずらいですかね。どうでしょう。


seasar-javadoc メーリングリストの案内