[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 メーリングリストの案内