AbstractContextを使ったCDIコンテキストの実装 (1)

DeltaSpike 0.4-incubatingでは、現在、JSF関連のモジュールが開発中されているところです。最近になって、@ViewScopedスコープのコンテキスト実装がコミットされています(DELTASPIKE-266)ので、今回はこれの実装方法について調べてみましょう。

@ViewScopedとは

@ViewScopedはJSF 2.0で導入されたスコープでJSFのViewにBeanを格納できるものです(正確に言えば、UIViewRoot.getViewMap()で取り出すことができるマップに格納されます)。これを使うと、JSFの画面が有効な間だけ存在するようなBeanを管理できまので、Ajaxアプリケーションが画面ごとに保持するデータをキャッシュとして格納するのに利用できます。

JSF 2.0の仕様では、@ViewScopeに格納されるオブジェクトはCDI Beanではなく、@ManagedBeanとなっています。このため、@ViewScopedで宣言したBeanをCDIの@Namedと組み合わせて使うことはできないという制限があります(Stack Overflowの記事を参照のこと)。DeltaSpikeで実装している@ViewScopeはこの制限を取り除いた、CDIで実装したスコープになります。

CDIカスタムコンテキストの作り方

CDI Extension SPIを使ってカスタムコンテキストを実装するためには、CDIのContextインタフェースを満たすクラスを実装し、このコンテキストをコンテナに登録するようなCDI拡張を作る必要があります。一般的なコンテキスト実装の方法はこのブログで過去に書いた記事にありますので、参考にしてください。

@ViewScoped用のコンテキストを作るには次のようにすれば良いでしょう。

  • @ViewScopedに対応するコンテキストを実装する
  • そのコンテキストに格納するBeanはUIViewRoot.getViewMap()で取得するマップに格納する
  • このViewが破壊されるタイミングでコンテキストを破棄する(それに伴い、コンテキストに格納されたすべてのBeanを破棄する)

AbstractContext 抽象クラス

DeltaSpikeでは@ViewScopedを実装するにあたり、まずAbstractContextというカスタムコンテキスト実装のための抽象クラスを定義し(DELTASPIKE-274)、それを拡張する形でViewScopedContextクラスを実装しています。

AbstractContextにはカスタムクラスを作成するためのロジックがまとめられていて、そのサブクラスはBeanを管理するための詳細を提供するようになっています。AbstractContextを継承したViewScopedClassはコンテキストに格納するBeanを保存するためのContextualStorageを返すgetContextualStorage()を実装します。ContextualStorageは内部でContextualInstanceInfoのマップを保持します。ContextualInstanceInfoはBeanとCreationalContextから構成されます。なぜ、BeanとCreationalContextを一緒に管理する必要があるかについては以下の記事の「CDIコンテナはどこでCreationalContextを保持するのか」に書きましたのでご覧下さい。

さて、AbstractContextの構造と使い方がわかったので、次回は実際にこのクラスを使ってカスタムコンテキストを作ってみようと思います。

広告

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中

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