Spring Framework integration

Seam 1.1.7RC1がリリースされました。Seam 1.1.7ではSeamとSpringの統合が実現されます。すでにSpringを使って構築されたシステムのWeb UI部分をSeamで書き直したい、なんて場合は便利そうです。できることは次のとおり:

  • Spring beanにSeam componentを注入
  • Seam componentにSpring beanを注入
  • Spring beanのSeam comonent化
  • Spring beanで任意のSeamコンテキストをカスタムスコープとして指定

さて、マニュアルを読むとステートフルなモデルのSeamステートレスなモデルのSpringの間のギャップに注意するようにと書かれています。これをマニュアルではscope impedanceと呼んでいます(O/Rマッピングではインピーダンス・ミスマッチという言葉がありますが、そのノリですね)。ステートフルなモデルではコンポーネントは変化しますが、ステートレスなモデルはそのような想定は置いていないからです。

具体的には、singleton Spring beanにConversation scopeのSeam componentが注入された場合、そのSpring beanはその参照先のオブジェクトの内部状態が変化したり、そのスコープの終了に伴い廃棄される、ということは想定していないでしょう。ですから、Seamの上位のスコープのcomponentがSpring beanに注入することがあれば、それには細心の注意が必要になるということです。そんなこと、普通はしないでしょうけどね。

atomic conversation

SeamはステートフルなWebフレームワークです。その背後にはJPAHibernateといったO/Rマッパーが控えています。従来のステートレスWebフレームワークとO/Rマッパーの組合せは、Viewの表示のときにはすべての表示データがDBから取得されていなければならないという問題がありました(いわゆるLazyInitializationExceptionの問題です)。EJB3では、この問題はExtended Persistence Contenxtで解決されました(過去の日記参照)

Seamでは、Extended Persistence Contextをconversation scopeで管理するというManaged Persistence Contextというものを提供しています。これを使えば、conversationが終了されるときPersistence Contextも自動的に破棄されるので、プログラマはPersistence Contextのライフサイクルのためのコードを書く必要がありません。まさに、WebフレームワークとEJBの「つなぎ(Seam)」ですね。

これに加えて、Seam 1.1からは、conversationの終了と同時にDBコミットが行われるatomic conversationという機能が導入されています(@Endでコミットということ)。Persistence ContextがDBと同期するのはトランザクションの終了時ですが、atomic conversationではリクエスト毎にトランザクションが実行されることがないので、サーバアクセスが頻繁に発生し、その会話の間にメモリに値をキャッシュするようなAjaxアプリケーションで重宝されます。以下はGavinのインタビューから引用。

An atomic conversation is basically a conversation where you can make changes to your persistent objects over many requests to the server, but those changes only become persistent when the conversation ends (or at some other well-defined point). This is a really common thing to want to do in Ajax-based applications.