Java EE 7 CDIを使う際の注意点──『Java EE 7徹底入門』番外編 第2回

Oracle Java & Developers編集部
2016-03-23 11:00:00
  • このエントリーをはてなブックマークに追加

@ConversationScopedを使う際にはリダイレクト操作の扱いに注意

 続いて@ConversationScopedを取り上げます。これは開発者がスコープを定義できる機能です。スコープは、begin()、end()の組み合わせやタイムアウトとして指定します。

 この機能を使う際には、1つ気をつけていただきたいことがあります。

 @ConversationScopedはJSFのリクエスト処理とは自動的にひも付くのですが、その他のリダイレクトなどの操作については、明示的にCIDを使って戻らないと新規のConversationとして扱われてしまうという点です。新規のConversationとして扱われると、元の情報は失われてしまいます。このようなケースもあるので、@ConversationScopedを使う際にはご注意ください。

EJB依存のトランザクションから脱却する

 最後に、CDIとトランザクションについて触れておきましょう。これは『Java EE 7徹底入門』に書きたかった話題なのですが、JTA(Java Transaction API) 1.2などともかかわる内容であるため、紙幅の都合から割愛しました。

 JTAはJava EE 7でバージョン1.2(JSR 907)にバージョンアップされ、いくつかのアノテーションが追加されました。この背景には、EJBに依存せずにトランザクションを扱えるようにしたいというニーズに応える目的があるのではないかと推測しています。

 CDIにおけるトランザクションの扱いに関して、開発者が覚えることはごくわずかです。パッケージjava.transaction、アノテーション@Transactional、そしてトランザクション属性を定義する要素Transactional.TxTypeです。

 アノテーション@Transacitonalでは、EJBの場合と似たような形式でトランザクション境界を指定します。クラスとメソッドのどちらでも定義することができ、例えばメソッドに定義すると、それが呼び出された際、Transactional.TxTypeで指定されたトランザクションが開始されます(Transactional.TxTypeは、EJBのTransactionAttributeTypeと同じものです)。@TransactionalはJTAのアノテーションであるため、CDIビーン以外でも使うことができます。

 もう1つ、JTAでは@TransactionScopedというアノテーションが使えますが、そのスコープは「現在有効なJTAトランザクションの実行に合わせたライフサイクルを持つもの」となります。その呼び出しのイメージは下図のようになります。

 図に示すように、トランザクション内だけで利用するオブジェクトとして扱えるため、オブジェクトがトランザクション後も長期間ヒープに保持されるような事態を回避することができます。

CDIをいかに使いこなすかが今後のJava EE開発者の課題

 CDIは、「EJBだけでは、スピードが要求される現代の開発スタイルに対応できない」、「EJBは重たすぎる」といった声に応えて導入された技術です。ただし、私は全てをCDIに置き換えるのが最適だとは思いません。

 例えば、業務上、近しい処理やデータ・モデルでは密結合が適している場合もあるでしょう。また、CDIで開発している際、EJBのようなプールが欲しくなるときもありますし、CDIを多用するとスコープを制御しきれなってしまう場合もあります。CDIだけで済ませることにこだわらず、EJBが得意な処理はEJBに任せればよいのです。

 私は、CDIの登場により、最近はビジネスロジック層の開発が"フリーダム"になりすぎてしまったという印象を受けています。そうした中で、「CDIとEJBのいずれかに固執するのではなく、両者を組み合わせて使おう」と考える現場も増えてきているようです。使い分けで迷ったら、まず簡単に実装できるほうを使用し、それぞれを使う領域を徐々に定めながら共存させていくというアプローチをとってもよいでしょう。

 ビジネスロジック開発の領域では、CDIの活用による簡素化が進む一方で、アンチパターンが確立されていないという問題も見られます。ここまでに何度か「使いすぎは良くない」とお話ししましたが、現在はその程度のノウハウしかないようです。今後は、アンチパターンを意識してノウハウや事例を蓄積していきたいと思っています。

 このような現状で確実に言えるのは、『Java EE 7徹底入門』にも書いたように「インジェクションの多用はやめよう」ということです。実際、インジェクションを使いすぎたためにOracle WebLogic Serverで問題が生じたというケースもいくつか見てきました。いずれも大規模開発の現場でしたが、設計者が意図していないインジェクションが数十の単位で発生し、リソースを使いすぎていたのです。この問題をどう解消していくかは、今後、全てのJava EE開発者が考えていかなければならないテーマの1つです。これをフレームワークで制御するのは"開発の簡素化(Ease of Development)"のコンセプトにそぐわないことのような気がしますし、だからといって設計でカバーできるのか……、ここは悩みどころですね。

 以上、今回は"Java EE 7徹底入門:番外編"として、Java EE 7のCDIを使う際の注意点を紹介した。次回は、新たに追加されたバッチ処理機能のjBatchを取り上げる。

このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]