[Seasar-user:19589] Re: 【ご質問】S2ContainerのDI対象クラスインスタンス生成について

Kensaku Takaki [E-MAIL ADDRESS DELETED]
2010年 4月 2日 (金) 22:23:15 JST


小林様

お世話になっております。高木です。

丁寧なご説明ありがとうございました。
勘違いもいくつもあり、ご説明いただき随分すっきりしました。

以上です。

> 小林 (koichik) です.
> 
> Date:    Thu, 1 Apr 2010 12:49:15 +0900
> From:    [E-MAIL ADDRESS DELETED]
> To:      [E-MAIL ADDRESS DELETED]
> Subject: [Seasar-user:19584] 【ご質問】S2ContainerのDI対象クラスインスタンス生成について
> 
> > 質問:DI対象クラスをprototypeで指定し、同じcomponentを2回取得する場合、2
> > 回目はインスタンス生成した後、取得する
> >     と書籍等に記載されておりますが、ソース上で具体的にどこで実装されて
> > いるのでしょうか?
> 
> prototype の場合,1 回目も 2 回目も
> インスタンスを生成して返します.
> 該当するコードは
> 
> org.seasar.framework.container.deployer.PrototypeComponentDeployer
> 
> です.
> コンポーネントのライフサイクルに関しては
> deployer パッケージ,DI に関しては
> assembler パッケージが中心になります.
> 
> >         2.DIコンテナ生成(対象メソッドinit)
> >                 XML解析→DIコンテナ生成→初回キャッシュ
> >                 SingletonS2ContainerFactory.init();
> 
> 「初回キャッシュ」というか,
> SingletonS2ContainerFactory は S2 コンテナを
> シングルトン (厳密には違いますが,どこからでも
> 同じコンテナを取得できるという意味) として扱う
> クラスです.
> 
> >                 ・初回キャッシュは
> >                         
> > org.seasar.framework.container.factory.ComponentTagHandlerクラスのstart(
> > )メソッドで
> >                         componentClass = ClassUtil.forName(className)を用
> > い、インスタンス生成しています。
> 
> ここではクラスを取得しているだけで,
> インスタンスは生成していません.
> 
> singleton の場合は,この後
> S2ContainerImpl#init() → ComponentDefImpl#init()
> → SingletonComponentDeployer#init() で
> インスタンスが生成されます.
> 
> >         3.コンポーネント取得(1回目)(対象メソッドgetComponet)
> >         4.コンポーネント取得(2回目)(対象メソッドgetComponet)
> 
> 1 回目と 2 回目で違いはありません.
> prototype の場合はいずれの場合も前述の
> PrototypeComponentDeployer でインスタンスが
> 生成されます.
> 
> > 3のコンポーネント取得の場合、DIコンテナへキャッシュしたものを取り出すと思
> > うのですが、4の動き(2回目のコンポーネントのインスタンス化)
> > をまだ把握出来ておりません。
> 
> prototype はキャッシュしません.
> っていうか,コンポーネントの管理については
> 「キャッシュ」という表現は不適切だと思います.
> singleton なら唯一のインスタンスを保持しますが
> (SingletonComponentDeployer 参照),それが
> 本質的なものであってキャッシュというわけでは
> ありません.
> 
> 「初回キャッシュ」という用語が連発されて
> いますが,コンポーネントのインスタンスに
> 関してはキャッシュはしていないと考えてください.
> リフレクションに関する情報などはキャッシュして
> いますが.
> 
> 文面からは,コンテナとコンポーネント,
> クラスとインスタンスが混同されているように
> 見えます.
> これらの区別を意識するようにするといいのでは
> ないかと思います.
> 
> S2Container の動作を理解するなら,
> Factory から追いかけるより,以下のように
> コンテナを組み立てる方が簡単ではないかと
> 思います.
> 
> public void test() throws Exception {
>   S2ContainerImpl container = new S2ContainerImpl();
> 
>   ComponentDefImpl cd1 = new ComponentDefImpl(Foo.class, "foo");
>   container.register(cd1);
> 
>   ComponentDefImpl cd2 = new ComponentDefImpl(Bar.class, "bar");
>   cd2.setInstanceDef(InstanceDefFactory.PROTOTYPE);
>   container.register(cd2);
> 
>   container.init();
> 
>   Foo foo1 = (Foo) container.getComponent(Foo.class);
>   Foo foo2 = (Foo) container.getComponent(Foo.class);
>   assertSame(foo1, foo2);
> 
>   Bar bar1 = (Bar) container.getComponent(Bar.class);
>   Bar bar2 = (Bar) container.getComponent(Bar.class);
>   assertNotSame(bar1, bar2);
> }
> 
> singleton のコンポーネント (Foo) は,
> 前述したように container.init() の際に
> インスタンスが生成されますが,prototype の
> コンポーネント (Bar) はその時点では
> インスタンス化されず,getComponent() の
> 度にインスタンス化されます.
> 
> 
> -- 
> <component name="koichik">
>     <property name="fullName">"Koichi Kobayashi"</property>
>     <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
>     <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
> </component>
> 
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user

-- 
Kensaku Takaki <[E-MAIL ADDRESS DELETED]>



Seasar-user メーリングリストの案内