BeanリファレンスとCreationalContext (3)

「BeanリファレンスとCreationalContext」というテーマで、過去2回に渡ってCreationalContextの役割を調べてきました。

今回はCreationalContextの破棄についてです。拡張モジュールを作るという流れからだいぶ横道に逸れてしまったので、これでCreationalContextをテーマにしたブログはひとまず区切りとしたいと思います。

Beanインスタンス破棄とCreationalContextとの間の関連

Beanのインスタンスが解放される流れを整理してみましょう。コンテキストが終了してから、それに関連付けられたBeanが破棄されるシーケンスは以下のようになります。

1. AbstractContext::destory()
1-1 Contextual::destroy(T instance, CreationalContext<T> creationalContext)
1-1-1.  <<コンテキストの種別に依存した処理>>
1-1-2.  CreationalContext::release()

CDI仕様書では意外なことにContextインタフェースにdestroyのようなpublicメソッドは定義されていません。Weld1.1.2実装では、org.jboss.weld.context.AbstractContextでdestroy()メソッドが定義されています。

Contextual::destroy()の具体例を見てみましょう。前回に引き続き、再びこのブログのBean<MyBean>の定義を見てください。MyBean::destroy()メソッドの引数としてCreationalContextが引き渡されています(これはcreate()で渡されたものと同じインスタンスである必要があります)。destory() メソッド実装内部ではpreDestroy()やdispose()のメソッドの実行後に、CreationalContextのrelease()が呼び出されています。

public void destroy(MyBean instance,
                    CreationalContext ctx) {
 log("Bean::destroy");
 it.preDestroy(instance);
 it.dispose(instance);
 ctx.release();
}

最後の行のrelease()メソッドは、Beanのすべての依存オブジェクトを破棄します。CreationalContextの実装は、release()が呼び出されたタイミングで、その中に蓄えているインスタンスを解放します。

CDIコンテナはどこでCreationalContextを保持するのか

Beanインスタンスが生成されるのはBeanがインジェクトされるときで、そのライフサイクルはコンテキストによって管理されます。CreationalContextが生成されるのは、トップレベルの(言い換えればRootになる)Beanインスタンスが生成されたとき、と考えられます。そして、コンテキストが終了するときに生成したときに使ったCreationalContextを使ってBeanインスタンスを破棄します。

では、一体、CDIコンテナはどこでCreationalContextのインスタンスを保持するのでしょうか。

Weld実装では、org.jboss.weld.context.api.ContextualInstanceがBeanに関する以下の3点の情報を保持していて、CDIコンテキストがこのContextualInstanceの集まりを管理するという構造になっています。

public interface ContextualInstance {
 public T getInstance(); // コンテキストで管理するインスタンス(例: MyBean)

 public CreationalContext getCreationalContext();

 public Contextual getContextual(); // インスタンスを生成するBean (例: Bean)
}

このContextualInstanceは、CDIのコンテキストのget()にアクセスしたときに、コンテキストにバインドするインスタンスが存在しない場合に生成されます(つまり、これまでBeanインスタンスと漠然と呼んでいたものが実はこのような構造を持って実現されていたということです)。Weld実装ではAbstractContext.javaの125行めがこれに相当します。

さて、ここまでWeldのソースを見てきたおかげでCDIコンテキスト周辺の作りが理解できたような気がします。次回は、CDI拡張モジュールを作る上で重要なBeanManagerについて書こうと思います。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。