Comments
Transcript
WAS × Webフレームワーク連携手法 ISE Conf. L-2 2008/06/06
【ISE Conf. L-2】 WAS × Webフレームワーク連携手法 2008/06/06 日本IBMシステムズ・エンジニアリング(株) Webインフラストラクチャー 植田佳明([email protected]) 2008 IBM Japan Systems Engineering Co., Ltd. ご注意 この資料に含まれる情報は可能な限り正確を期しておりますが、日本アイ・ビー・エム システムズ・エンジニアリング株式会社の正式 なレビューを受けておらず、当資料に記載された内容に関して当コンファレンスの主催者である日本アイ・ビー・エム システムズ・エ ンジニアリング株式会社は何ら保証するものではありません。 従って、この情報の利用またはこれらの技法の実施はひとえに使用者の責任において為されるものであり、資料の内容によって受けたい かなる被害に関しても一切の保証をするものではありません。 当資料をコピー等で複製することは、日本アイ・ビー・エム システムズ・エンジニアリング株式会社および執筆者の承諾なしではでき ません。また、当資料に記載された製品名または会社名はそれぞれの各社の商標または登録商標です。 2 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 目次 1. フレームワークとは? 2. フレームワークを用いたWASアプリケーション開発 3. フレームワークの歴史および今後 4. (参考)WASと連携させる上でのHints & Tips 3 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 1.フレームワークとは? この章ではフレームワークの概要およびその利点をお話します。 4 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. まず、フレームワークってなんでしょう? 基盤として再利用される汎用的なパターンや枠組み – 同様に再利用されるものにライブラリーがあるが、それよりも大きな粒度の機能/非機能要件を実現する フレームワークとライブラリーとの違い – フレームワーク ・・・ アプリケーションの基盤となる骨組み – ライブラリー ・・・ アプリケーションの一部を構成する要素 フレームワークという基盤の上で、ユーザー・コードやライブラリーが呼び出されて稼 動する アプリからライブラリーを呼び出す ライブラリー ユーザー コード① ユーザー コード② ライブラリー 呼び出し 呼び出し 呼び出し 呼び出し 基盤として稼動するフレームワーク アプリケーション実行環境(J2EEコンテナー) 5 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. J2EEシステムにおけるフレームワーク採用の利点 1. フレームワークが実装すべき枠組みを提供してくれる 2. フレームワークが開発方式を規定してくれる 1. アーキテクチャーを考慮したアプリケーション設計が容易 – – 2. – – 明確なレイヤー化 – プレゼンテーション層、ビジネス層、データアクセス層の分離 明確にレイヤー化された デザインパターンの活用 アプリケーション設計が容易 – Service to Worker (Struts) – Factory Method (Spring) プレゼンテーション層 – Singletonなどなど 開発生産性の向上と品質の統一 ビジネス層 レイヤーごとの開発、保守が容易 コーディング量の減少 データアクセス層 レイヤーごとの 開発、保守が容易 6 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. フレームワーク採用による効果の例 システム開発でよく起こる問題への対応が容易になる 短納期、低コスト化・・・ – Webシステムは納期までのスピードが求められる傾向にある – 設計や実装に費やせる時間が短い フレームワークが枠組みを提供することにより、短期間での設計と実装が可能となる 曖昧な仕様と要求: 急な仕様変更とメンテナンスへの対応に追われる・・・ – 急な仕様変更を求められる場合がある – 仕様変更に伴う影響を小さくする必要がある フレームワークによりレイヤー間の依存性がなくなり、コードの保守性が高まる 開発者の技術レベルに差がある・・・ – 限られたコストで技術者を雇わなければならない – 開発にあたって習得すべき知識、技術(J2EE)が多い フレームワークが複雑な処理を隠蔽してくれるため、実装をPOJOでおこなえる 7 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. フレームワークの各層ごとの位置づけ テスト・ フレーム ワーク プレゼンテーション層 ビジネス層 データアクセス層 8 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. プレゼンテーション層のフレームワーク プレゼンテーション層の役割 – – – – プレゼンテーション層 ユーザーからの入出力制御 画面遷移のコントロール バリデーション・チェック ビジネス・ロジックを呼び出し ビジネス層 データアクセス層 大きく3つのパターンに分けることができる 9 特徴 メリット/デメリット どういうケースで有効か 代表的なフレームワーク アクション指向 ユーザーのリクエストを1つ のアクション・クラスと紐付け て処理を記述する考え方 画面とアクションをわけることで分業 がしやすくなる アクションの再利用性を高めることが 可能となる 画面遷移が複雑になると画面とアク ションの関係がわかりにくくなる 画面デザインはデザイナー、 機能はプログラマーという担 当の切り分けが容易なため、 画面と機能の担当を分離でき る場合に力を発揮 Struts コンポーネント イベント指向 画面のUI部品をコンポーネ ント化して、スタンドアロンの GUIアプリケーションのよう に開発する考え方 GUIツールによる画面デザイン効率 の向上 コンポーネント化によるUI部品の再 利用 コンポーネント共有の容易性 コンポーネント共通チームが 共通機能を作成し、プログラ マーがそれを再利用する、と 分業することで、大規模開発 においても設計思想の維持し た開発がしやすい JSF(標準仕様) Tapestry ページ指向 画面とクラスを対応させ、画 面のイベント処理をクラスの メソッドに対応させる考え方 画面とクラスの関係がわかりやすく、 可読性が高い ページ指向=「コンポーネントイベン ト指向」+「画面とクラスの関係が決 まっている」 簡単な画面遷移が多いアプ リケーション 経験の少ないプログラマーが 多い Click Teeda Wicket WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. ビジネスロジック層のフレームワーク ビジネスロジック層の役割 プレゼンテーション層 – 業務のビジネスロジックを実装 ビジネス層 – トランザクションの制御 データアクセス層 大きく3つに分けることができる EJB 2.1 特徴 メリット/デメリット 代表的なフレームワーク アプリケーションのコンポーネント化を可能 とする 開発者はトランザクション制御を意識せ ずに開発可能であり、ビジネスロジックに 集中できる ただし、EJBの複雑な仕様に準拠した環 境(EJBコンテナ)でしか稼動しないため 単体テストが難しい EJB 2.1 (標準仕様) 「トランザクションとセキュリティの管理」「分 散トランザクション」などをコンテナが提供 10 EJB Alternativeとし ての軽量コンテナ (DI/AOPコンテナ) DI / AOP という技術をベースにした(EJBよ りも)軽量なコンテナを提供 EJBのようなコンポーネントの疎結合化を POJOベースで可能とする ビジネス・ロジック層だけではなく、各層をつ なぐレイヤー間接続のための機能を提供す る コンテナへの依存を排除したアプリケー ション開発が可能となる(テスト容易性) EJBと同様にアプリケーション(ビジネス ロジック)からトランザクション制御を分離 可能なので、開発者はトランザクションを 意識せずに開発可能 ただし、標準仕様ではない、設定ファイル が多くなるなどのデメリットはある Spring Seasar2 EJB 3.0 これまでのEJBへの批判を受け入れ、軽量 コンテナの良さを取り入れた POJOベース開発とアノテーション・ベース 設定によりEoDを実現 EJB2.1の機能を保持した上で軽量コン テナに近いEoDを標準仕様として実現 ただし、DI/AOPが適用できる範囲が限ら れているなど、これからの改良が待たれ る点もある EJB3.0 (標準仕様) WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. データアクセス層のフレームワーク プレゼンテーション層 データアクセス層の役割 – データソースへのアクセスする方法をDAOパターンとして提供 ビジネス層 – オブジェクトとデータベースをつなぐO/Rマッピング機能の提供 データアクセス層 大きく2つのパターンに分けることができる SQLを隠蔽するも の 特徴 メリット/デメリット 代表的なフレームワーク O/Rマッピング設定をXMLへ記述す ることで、フレームワークがSQL文を 生成 開発者が高度なSQL文の知識を持たなくとも 開発が可能 Hibernate Toplink Essentials (→ Eclipse Link ) JPA (標準仕様) SQL文によるチューニングが難しい SQLを隠蔽しない もの O/Rマッピング設定を外部設定ファ イルにSQL文を記述することで実現 開発者がSQL文を記述するので、SQL文によ るチューニングが可能となるので、SQLを詳し く理解している技術者を活かした開発が可能と なる iBatis S2Dao しかし、開発者がSQLへ精通していないと活用 することは難しくなる 11 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. フレームワークを適用するとどう変わる? ビジネス ロジック (Controller/View) (Model) データベース アクセス 典型的なJ2EEアプリのままでは・・・ – MVCの各層の役割分担があいまい EJB (Session Bean) – コンテナーへの依存が強い →開発と保守が面倒 →単体テストが難しい(特にEJB) Servlet/JSP 接 着 剤 プレゼン テーション EJB (Entity Bean) フレームワークを活用すると・・・ – MVCの各層の役割分担がより明確に – コンテナーへの依存を少なくできる ビジネス・ロジック (POJOとして記述) – 各層の結びつきを緩くできる →開発、保守が楽になる →単体テストが容易になる 12 WAS × Webフレームワーク連携手法 単体テスト JUnit Spring Struts Hibernate 2008 IBM Japan Systems Engineering Co., Ltd. 2.フレームワークを用いたWASアプリケーション開発 実際のWAS V6.1でのアプリケーション開発を通してフレーム ワークの利点を見ていきます。 13 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 概要 WAS V6.1でフレームワークを使用しない場合と使用する場合とでアプリ ケーションがどのように変わるかを比較する フレームワーク使用/不使用の両方とも全く同一の機能を持つこととする 作成するアプリケーション – ショッピングサイト – 商品一覧画面から購入する商品を選択 – 購入すると買い物かごに入る – 確定画面で受付け番号を発行 購入 14 WAS × Webフレームワーク連携手法 確定 2008 IBM Japan Systems Engineering Co., Ltd. 2.1 フレームワークを使用しない場合 15 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 検証環境 使用技術 – J2SE 5.0 / J2EE 1.4 開発ツール – Rational Application Developer 7.0 動作環境 – WebSphere Application Server Network Deployment V6.1 – DB2 V9.1 16 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. アプリケーションの構造 -1 フレームワークを使用しないでアプリケーションを作成 商品一覧 ① 内容をロード ② index.jsp 買い物かご SummaryServlet ③ CARTBL 購入金額の計算 ⑤ ④ summary.jsp 受付NO COUNTER CARDB ThanksServlet ⑥ 注文情報格納 thanks.jsp 17 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. アプリケーションの構造 -2 18 データーベースCARDB内に2つのテーブルを作成 – CARTBL (商品の一覧を格納) – COUNTER (確定した注文情報を格納) 表示部分は3つのJSPで作成 – index.jsp (最初にブラウザからアクセスする画面) – summary.jsp (選択商品および合計金額表示画面) – thanks.jsp (お礼と受付けNoの表示) ビジネスロジックはServletで作成 – SummaryServlet (合計金額を計算) – ThanksServlet (購入情報のDBへの格納) WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. アプリケーションの構造 -問題点要因 要因 問題点 問題点 1つ1つのJSPやServletがいろいろな機 能を持ち肥大化している アプリケーションの変更が難しい 各クラスが密接に関連し合っている 単体テストが難しい 同じコードが様々な場所に分散している コードの可読性が悪い 外部の変更に弱い ¾ データソースlookup ¾ トランザクション処理など ¾ DBのカラム追加など 開発/保守を考慮した設計が必要 19 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 2.2 フレームワークを使用した場合 20 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 検証環境 使用技術 – J2SE 5.0 / J2EE 1.4に加えて以下のフレームワークを使用 – Struts – Spring – Hibernate 開発ツール – Rational Application Developer 7.0 動作環境 – WebSphere Application Server Network Deployment V6.1 – DB2 V9.1 21 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. フレームワークの適用 Struts / Spring / Hibernateを用いて2.1で作成したアプリケーションを再構築 各フレームワークの適用イメージは以下 Struts 商品一覧 Spring Hibernate 内容をロード index.jsp SummaryServlet CARTBL 買い物かご 購入金額の計算 COUNTER CARDB summary.jsp 受付NO ThanksServlet 注文情報格納 thanks.jsp 22 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Strutsの適用 プレゼンテーション層のフレームワークとしてStrutsを使用 Struts 商品一覧 内容をロード index.jsp SummaryServlet CARTBL 買い物かご 購入金額の計算 COUNTER CARDB summary.jsp 受付NO ThanksServlet 注文情報格納 thanks.jsp 23 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Strutsとは Jakarta Project が提供するオープンソースのWebアプリケーション・フ レームワーク – Apacheライセンスに基づいて提供 – 最新バージョンは1.3.8 (2008年5月現在) – Webコンテナー上で動作(1.3.8の場合、Servlet2.3 / JSP1.2以上) – MVC Model 2 デザインを採用 1.Request (Controller) Servlet 2 3 5.Response (View) JSP ins tan tia te 4 Application Server 24 WAS × Webフレームワーク連携手法 (Model) JavaBean Enterprise Servers/ DataSource 2008 IBM Japan Systems Engineering Co., Ltd. Strutsの機能 MVC2に基づいたアプリケーションデザインを提供 – ActionServletと呼ばれるサーブレットがリクエストを受付ける。Actionクラスへの割振 りやJSPへのフォワードはRequestProcessorというクラスがおこなう。 – 実際の処理はActionクラスに記述 – ActionFormというJavaBeanを介してパラメータの受け渡しをする JSPカスタムタグライブラリ – 開発者が対話的なフォームベースのアプリケーションを作成するのをサポート その他、入力値チェック(Validator)、国際化サポート、画面レイアウト (tiles)などの機能を持つ Action クラス1 リクエスト送信 JSP ActionServlet RequestProcessor Model Action クラス2 フォワード Action Form 実際の処理を記述 パラメータの受け渡し 25 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Struts適用後 Struts 内容をロード LoadAction 商品一覧 CarListService index.jsp CARTBL 購入金額の計算 買い物かご SummaryAction SummaryService COUNTER CARDB summary.jsp 受付NO 注文情報格納 ThanksAction ThanksService thanks.jsp ActionServlet プレゼンテーション層 26 WAS × Webフレームワーク連携手法 ビジネス層 + データアクセス層 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Struts適用前 JSPへのフォワード 買い物かご SummaryServlet summary.jsp SummaryServlet public class SummaryServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { ・・・省略・・・ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ・・・省略・・・(ビジネスロジックを実行など) ServletContext servletContext = getServletContext(); RequestDispatcher dispatcher = servletContext.getRequestDispatcher("summary.jsp"); dispatcher.forward(request, response); } SummaryServlet内でsummary.jspへの フォワードを実行 27 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Struts適用後 JSPへのフォワードについて 買い物かご ActionServlet SummaryAction summary.jsp struts-config.xml <action-mappings> <action path=“/summary” type=“sd.fw.sdstrutsweb.actions.SummaryAction” name="cartForm" scope="request"> <forward contextRelative=“false” name=“success” path="/summary.jsp"></forward> </action> ・・・省略・・・ 設定ファイルでsummary.jspへのフォワードを定義 </action-mappings> Actionクラスを継承 SummaryAction public class SummaryAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ・・・省略・・・ forward = mapping.findForward("success"); return (forward); struts-config.xmlの定義と連携。実際 } のフォワードはstrutsがやってくれる。 } 28 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Struts適用でどう変わったか? 画面制御を設定ファイルで一括管理できる – Struts設定ファイル(struts-cfg.xml)に記述 コンポーネント間(View-Controller)の疎結合化 – View部分は独立するので、作業分担がしやすくなる – ただし、Actionクラス-ビジネス・ロジック(Controller-Model)間は必ずしも疎結合にはなら ない – ビジネス層(Model)部分はStrutsでは規定されない 29 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Spring Frameworkの適用 プレゼンテーション層とビジネス層を疎結合にするためにSpring Frameworkを用いる Struts Spring 内容をロード LoadAction 商品一覧 CarListService index.jsp CARTBL 購入金額の計算 買い物かご SummaryAction SummaryService COUNTER CARDB summary.jsp 受付NO 注文情報格納 ThanksAction ThanksService thanks.jsp ActionServlet プレゼンテーション層 30 WAS × Webフレームワーク連携手法 ビジネス層 + データアクセス層 2008 IBM Japan Systems Engineering Co., Ltd. Spring Frameworkとは Rod Johnson氏を中心に開発された、オープンソースのJavaフレーム ワーク – Apacheライセンスに基づいて提供 – 最新バージョンは2.5.4 , 2.0.xでは2.0.8(2008/5/9現在) – 多岐にわたる機能を実装するフル・スタックフレームワーク – – – – Spring MVC Spring JDBC Spring DI Spring AOP – DIxAOPコンテナして使用されることが多い 31 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Springの機能 (DI x AOPコンテナ) DI (Dependency Injection) – 依存性(必要なコンポーネントやプロパティ)を外部から注入 – 「外部から依存性注入」をおこなうものをDIコンテナと呼ぶ 定義の読 み込み Class HelloClass 実装クラス Interface Bean 定義ファイル 定義に従って 実装をセット AOP (Aspect Oriented Programming) DIコンテナ – AOPは横断的関心事をクラスの定義から分離し、必要に応じて挿入するという形をとる – 横断的関心事とは中心となるビジネスロジック以外の処理(ロギング、トランザクション制御な ど)で、複数のモジュールに散在するものを言う。 モジュールA ログ処理が 散在 32 モジュールB WAS × Webフレームワーク連携手法 モジュールA モジュールB Spring AOP ログ処理 2008 IBM Japan Systems Engineering Co., Ltd. Strutsフレームワークとの連携 SpringのDIコンテナを使用することでActionクラスとモデル層のビジネス ロジッククラスとの疎結合化が可能 Strutsとの連携用にSpring側で2つのクラスが用意されている – ActionSupport – DelegatingActionProxy Springで疎結合化 Controller ActionServlet Model マッピン グ情報 ビジネス ロジック Action 疎な結合に するべき Action ビジネス ロジック JSP JSP View 33 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. ActionSupportを使用した連携 ActionSupportとは – ActionSupportを継承することによりActionクラスからSpringの機能が使用可能に なる Spring側で用意されたDelegatingActionProxyを使って、StrutsのActionクラスごとDIコ ンテナによって管理する方法もある Controller Struts Model マッピン グ情報 Spring ActionServlet Action Action JSP JSP Action サポートクラス ビジネス クラス ビジネス クラス DI View 34 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Spring Framework適用後 ※ Struts DI : SpringのDIによって依存性注入 Spring LoadAction 内容をロード <<Interface>> CarListService 商品一覧 CarListServiceImpl DI index.jsp SummaryAction 買い物かご CARTBL 購入金額の計算 <<Interface>> SummaryService SummaryServiceImpl COUNTER DI CARDB summary.jsp ThanksAction 注文情報格納 受付NO <<Interface>> ThanksService ThanksServiceImpl DI thanks.jsp ActionServlet プレゼンテーション層 35 WAS × Webフレームワーク連携手法 ビジネス層 + データアクセス層 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Spring適用前 Spring適用前のActionクラス LoadAction CarListService StrutsのActionクラスを継承 LoadAction public class LoadAction extends Action { public ActionForward execute(ActionMapping map,ActionForm form,HttpServletRequest request,HttpServletResponse response){ ・・・省略・・・ CarListServiceImplインスタンスをAction //Car一覧を取得 の中で作成 CarListService carListService = new CarListServiceImpl(); ArrayList<CarInfo> records = carListService.getRecords(); CarListServiceImplに依存 //DBのレコードrequestスコープに格納 request.setAttribute(“records”, records); //フォワード return map.findForward("success"); } } 36 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Spring適用後 Spring適用後 LoadAction 内容をロード <<Interface>> CarListService CarListServiceImpl DI LoadAction Struts連携用のActionSupportクラスを継承 public class LoadAction extends ActionSupport { public ActionForward execute(ActionMapping map,ActionForm form,HttpServletRequest, request,HttpServletResponse response){ ・・・省略・・・ //Car一覧を取得(Spring Stuts連携機能を利用) CarListService carListService = (CarListService)getWebApplicationContext().getBean("carListService“); List records = carListService.getRecords(); ・・・省略・・・ ActionSupportクラスで定義されているgetWebApplicationContextメ } ソッドを利用。carListServiceというIDでSpringによって注入されたイ } ンスタンスを取得 CarListServiceImplには依存しない applicationContext.xml (Bean定義) <beans> <bean id=" carListService" class="sd.fw.sdstrutsweb.service.CarListServiceImpl“> </bean> </beans> carListServiceの定義。実際にはCarListServiceImplのインスタンス 37 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Spring適用でどう変わったか? DIの使用により、依存関係が排除できる – レイヤーをまたぐ呼び出しをインターフェース経由にし、その実体をSpringでDIすることに よってレイヤー間を疎結合にすることができる。 Strutsとの連携 – Strutsのみの適用時に問題であったController-Model間の分離が可能 – 他にもJSF、Hibernate、iBatisなどとの連携がサポートされている 38 設定ファイルが煩雑に WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Hibernateの適用 データアクセス層のフレームワークとしてHibernateを使用 Springと連携してビジネス層とデータアクセス層を疎結合にする Struts Spring LoadAction 商品一覧 Hibernate 内容をロード <<Interface>> CarListService CarListServiceImpl DI index.jsp SummaryAction 買い物かご CARTBL 購入金額の計算 <<Interface>> SummaryService SummaryServiceImpl COUNTER DI CARDB summary.jsp ThanksAction 注文情報格納 受付NO <<Interface>> ThanksService ThanksServiceImpl DI thanks.jsp ActionServlet プレゼンテーション層 39 WAS × Webフレームワーク連携手法 ビジネス層 + データアクセス層 2008 IBM Japan Systems Engineering Co., Ltd. Hibernateとは オープンソースで開発されているO/Rマッピングツール – LGPLオープンソースライセンスで配布 – 最新バージョン: 3.2.6 (2008年5月現在) – JPA (Java Persistence API) に対応 O/Rマッピング – オブジェクトとリレーショナル(主にRDBレコード)の間にある差異を吸収してリレーショナルに格納され ているデータをオブジェクトとして直感的に扱いやすくするための仕組み 以下のようにマッピングされる – クラス⇔テーブル – フィールド⇔カラム – インスタンス化されたオブジェクト⇔レコード 社員テーブル 支給日: 2007/01/25 支給額: 300000 社員ID 名字: たなか 名前: よしお 支給日: 2007/01/25 支給額: 250000 名前 126 たなか よしお 743 すずき はなこ 手当てテーブル 名字: すずき 名前: はなこ 支給日: 2007/02/10 支給額: 7000 40 名字 WAS × Webフレームワーク連携手法 Hibernate 手当てID 対象者ID 支給日 支給額 1 743 2007/1/25 300000 2 126 2007/1/25 250000 3 743 2007/2/10 7000 2008 IBM Japan Systems Engineering Co., Ltd. Hibernateの機能 アプリケーションとデータベースの間に位置してRDBレコードと対応するオブジェク トの管理をおこなう – 永続化先のデータベース定義やオブジェクトとテーブルのマッピング定義は各種設定ファイルでおこ なう(hibernate.cfg.xml / <Class名>.hbm.xmlなど) – オブジェクトはtransient/persistent/detachedの状態を遷移し、そのライフサイクル管理はHibernate がおこなう アプリケーション HQLと呼ばれるクエリ言語を提供 – オブジェクト オブジェクト SQLに対応するオブジェクトベースのクエリ言語 HQLの例 Hibernate from eg.Cat as cat where cat.name='Fritz' 更新 検索 eg.Catクラスのインスタンスでname属性がFritzで あるオブジェクトを検索 データベース 41 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Springフレームワークとの連携 Spring側でHibernateとの連携機能が用意されている – HibernateDaoSupport – Hibernateへのデータアクセスオブジェクト(DAO)作成のためのサポートクラス。作 成の際にはこのクラスを継承して使用する。 – HibernateTemplate – Hibernateのデータアクセスコード(追加、削除など)を簡略化 設定ファイルの統一 – SpringのBean定義ファイルにHibernate設定の一部を記述可能(hibernate.cfg.xmlが 不要に) Hibernate HibernateDao Support ビジネスロジック Bean定義ファイル DI 継承 (Hibernate設定も記 述) ビジネスロジック DI 42 Spring DIコンテナ WAS × Webフレームワーク連携手法 マッピング ファイル マッピング DAOクラス DI データ操作 永続化オブ ジェクト HibernateTemplate のメソッドを利用 2008 IBM Japan Systems Engineering Co., Ltd. Hibernate適用後 ※ DI : SpringのDIによって依存性注入 Spring Struts Hibernate 内容をロード LoadAction Cartbl CarListServiceImpl 商品一覧 <<Interface>> CarListService DI <<Interface>> CarDao DI index.jsp SummaryAction 買い物かご マッピング CarDaoImpl CARTBL一覧取得 クエリを実行 CARTBL 購入金額の計算 <<Interface>> SummaryService SummaryServiceImpl COUNTER DI マッピング summary.jsp 注文情報格納 ThanksAction 受付NO <<Interface>> ThanksService DI CARDB Counter ThanksServiceImpl COUNTERテーブル に対するクエリを実行 <<Interface>> CounterDao CounterDaoImpl DI thanks.jsp ActionServlet プレゼンテーション層 43 WAS × Webフレームワーク連携手法 ビジネス層 データアクセス層 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Hibernate適用前 Hibernate適用前のCarListServiceImpl CarListServiceImpl DB CarListServiceImpl InitialContext initialContext= null; Connection conn = null; ResultSet rs = null; Statement stmt = null; DataSource ds = null; String sql = "select CARNM, CARCMP, CARPRC from CARTBL"; try { initialContext = new InitialContext(); ds = (DataSource)initialContext.lookup(“java:comp/env/jdbc/cardbds"); conn = ds.getConnection(); SQLの実行 stmt = conn.createStatement(); rs = stmt.executeQuery(sql); while((rs.next())) { CarInfo record = new CarInfo(); データソースのlookup ・・・・ <省略>・・・・ } 44 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. コード比較 - Hibernate適用後 Hibernate適用後 Cartbl CarListServiceImpl <<Interface>> CarDao CarDaoImpl DI CarListServiceImpl public class CarListServiceImpl implements CarListService { private CartblDao cartblDao = null; public void setCartblDao(CartblDao cartblDao) { this.cartblDao = cartblDao; } ・・・省略・・・ List cartblrecords = cartblDao.findAll(); ・・・省略・・・ このSetterを通じてSpringはcartblDaoへ注入 CartDaoImplには依存しない DAO経由でDBのデータ一覧を取得 データソースのlookupは必要なし HibernateDaoSupportを継承 CarDaoImpl public class CartblDaoImpl extends HibernateDaoSupport implements CartblDao { public List findAll() { //HQL実行 List carList = getHibernateTemplate().find("from Cartbl"); return carList; } 45 前ページのSQL実行部分に相当 HibernateTemplateクラスのfindメソッドを使用してHQLを実行 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Hibernate適用でどう変わったか? アプリケーション側でのDB接続部分の考慮が少なくなる – 設定ファイルに従ってHibernate側で管理 – データソースlookupなどのコーディングは不要 SQL文を書く度合いが少なくなる – 複雑なクエリでない限り、永続オブジェクトに対するメソッド操作で代替が可能 Hibernate まかせになってしまうため、制御しにくい部分もある – 冗長なSQLに変換されてしまう – オブジェクトのライフサイクル管理などがHibernateまかせ 46 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 2.3 まとめ 47 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 問題点は解決されたのか・・・? 問題点 問題点 フレームワーク適用後 フレームワーク適用後 Spring DIおよびインターフェースの使用 により実装の入れ替えが容易に アプリケーションの変更が難しい 単体テストが難しい コードの可読性が悪い 外部の変更に弱い ¾ 48 DBのカラム追加など WAS × Webフレームワーク連携手法 レイヤー化により変更の際の影響範囲が 限定され、レイヤーごとにテストも可能に ビジネスロジックをPOJOとして実装でき るため単体テストがしやすくなり、コード の可読性も向上 コーディングではなく、設定ファイルの変 更によって対応できる部分が多くなる 2008 IBM Japan Systems Engineering Co., Ltd. フレームワーク適用についての考察 アーキテクチャーの理解 – フレームワークを使用することはフレームワークが採用しているアーキテクチャーを使用する ことになる アプリケーションがそのアーキテクチャーに適合するかどうかを考える必要がある – フレームワークの採用しているアーキテクチャーを理解することが必要 アーキテクチャーへの理解が不足していると十分に使いこなせない 学習コストと開発コスト – 新たにフレームワークを学習するのは労力が必要 学習コストと開発コストはトレードオフの関係にある – ある程度の機能はフレームワークが用意してくれるので覚えると設計・コーディングなどは楽 になる 設定ファイルへの記述のみでコーディング量が減る部分がある 49 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 3.フレームワークの歴史および今後 フレームワーク登場からの歴史および今後の展開についてお話 します。 50 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. J2EEとフレームワークのこれまでの歴史 J2EEの登場 エンタープライズJavaとしてJ2EEの登場 現在 Strutsの登場 オープン・ソース・フレームワーク黎明期 軽量コンテナ (DI/AOP) J2EE神話の崩壊 オープン・ソース・フレームワーク全盛期 Java EE 5 メインストリームの逆襲 ~ EJB3.0の進化 51 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. J2EEとフレームワークでみるWebアプリケーション開発の変遷 エンタープライズJavaとしてJ2EEの登場 – J2EEそのものがエンタープライズ・システムの基盤を支えるフレームワークとして登場した – アプリケーションをコンポーネント化して再利用するための枠組みを提供 – EJBによるポータビリティ、スケーラビリティ、の提供 オープン・ソース・フレームワーク黎明期 – J2EEを補完する基盤として生まれたフレームワーク – Struts: MVCモデルにおけるフロントエンド層の明確な分離 J2EE神話の崩壊 ~ オープン・ソース・フレームワークの全盛期 – 複雑なJ2EE(特にEJB)への批判精神により生まれたフレームワーク – Hibernate: アンチCMP、O/Rマッピングの代替 – Spring Framework: よりLight-weightコンテナを求めて – Rod Johnson 「EJB is too complex」(J2EE Development without EJB,2004) 逆襲のメインストリーム ~ EJB3.0の進化 – オープンソースの設計思想と技術トレンドをメインストリームとして取り入れ進化 – – – – 52 アノテーション・ベース POJO (Plain Old Java Object), POJI (Plain Old Java Interface) DI (Dependency Injection) JPA(Java Persistence API) ~ O/R マッピング機能の改善 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. これまでのJ2EEの進化とオープンソース・フレームワークの関係 J2EE 1.4 Servlet2.4 プレゼンテーション層 ビジネス層 Java EE 5 Servlet2.5 JSP2.1 JSP2.0 JSTL1.1 JSF1.2 EJB2.1 EJB3.0 (Session Bean) EJB2.1 データアクセス層 (Entity Bean) JDBC 3.0 53 オープン・ソース フレームワーク WAS × Webフレームワーク連携手法 JPA1.0 JDBC 4.0 2008 IBM Japan Systems Engineering Co., Ltd. Java EE はどう進化する?~Java EE 5 へ残された課題 1. JSFの開発生産性 – JSFは、GUIツールによる画面デザイン、コンポーネント化によるUI部品の再利用など、Strutsに変わる ものとして生まれたが、専用IDE(もしくはEclipseプラグイン)が必要であり、デファクトになったStrutsの 代替として使用するには依然として敷居が高い – StrutsはServlet/JSPを補完するフレームワークとしては依然としてデファクト 2. レイヤー間のデータ連携 – プレゼンテーション層、ビジネス層、データアクセス層の間でのデータのやりとりがシームレスな連携が 実現できていない – これまでDTO(Data Transfer Object)パターンによる仲介/詰め替え処理(コンポーネント間のワイヤリ ング)が必要であり、それぞれのコンポーネントを完全に疎結合なPOJOとして開発するには依然として ハードルがある – JPAをDTOとして使いまわすことも可能だが、プレゼンテーション層とデータアクセス層のオブジェクト存 続期間の違い(HTTP依存⇔トランザクション依存)があり、考慮すべき点が多いのが現実 3. JPA1.0の成熟度 – JPA1.0の段階ではオープン・ソース・フレームワーク(Hibernateなど)に機能面で追いつききれていない – クエリ言語(JPQL)の柔軟性など 54 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Java EE はどう進化する?~オープンソース・フレームワークでみる 1. Facelets : JSFの開発生産性をより向上 – HTML(XHTML)ベースのテンプレート・エンジンをJSFへ提供 – 専用IDEなしに、より簡単に、WYSIWYG(What You See Is What You Get:ウィジウィグ)な編集を 実現 – Faceletsの影響を受けた仕様として、 JSF2.0が策定中であり、Java EE 6へ取り込まれる予定 2. JBoss Seam : レイヤー間(JSFとEJB3.0の間)のデータ連携をシームレスに – DTOパターンによる仲介/詰め替え処理をコード記述することなく、JSF Managed Bean ⇔ エンティ ティBean という連携が可能 – コンポーネント間のワイヤリングを意識することなく、コンポーネントの開発が可能 – JBoss Seam は、JSR299:Web Beans として、Java EE 6 に取り込まれる予定 3. EclipseLink : JPA2.0の参照実装に – 現リリースのEclipseLink1.0はJPA1.0実装だが、今後のリリースでJSR317:JPA2.0(Java EE 6 に取 り込まれる予定)の参照実装として開発されていく予定 – 現時点では仕様策定中で詳細未定だが、EclipseLinkを通してJPA2.0の実装を追うことができる 55 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Java EE 6 の進化 Java EE 5 プレゼンテーション層 Java EE 6 Servlet2.4 Servlet3.0 JSP2.1 JSP2.2 JSTL1.1 JSF1.2 JSTL1.2 JSF2.0 EJB3.0 ビジネス層 オープン・ソース フレームワーク JSR299: Web Beans EJB3.1 データアクセス層 JPA1.0 JPA2.0 JDBC 4.0 56 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. まとめ フレームワークとは基盤として再利用される汎用的なパターンや枠組み – 採用することによって実績のあるアーキテクチャーを考慮したアプリケーション構築が可能に – アプリケーションの枠組みを提供してくれるため、設計、コーディングなどが容易に フレームワークを用いたアプリケーション構築 – Struts / Spring / Hibernateを用いたアプリケーション構築 – フレームワークを組み合わせることによって各レイヤーが分離され、疎結合されることによっ て保守性がすぐれたアプリケーション構築が可能 フレームワークの今後 – Java EEの仕様とオープン・ソース・フレームワークは影響しあいながら発展している – Java EE 6にもJBoss SeamやEclipseLinkなどで実装ずみの機能がとりこまれる予定 57 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 4.(参考)WASと連携させる上での Hints & Tips 58 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Spring/HibernateをWASと連携させるケースでの Hints & Tips 当資料では、以下の重要なポイントにしぼって解説 Spring×WAS 連携 の Hints & Tips – Spring Bean から WAS データソースを使用する方法 – Spring と WAS トランザクション管理との連携 – Spring と WAS スケジューリング機能の連携 – 非管理スレッドについての注意点 – Spring×WAS連携におけるクラスローダー設定に関しての考慮点 Hibernate×WAS 連携 の Hints & Tips – Hibernate から WAS データソースを使用する方法 – Hibernate と WAS トランザクションを連携させる方法 – Hibernate を使用したデータソースにおいて、複数の分離レベルをサポートするには 59 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. Spring Bean から WAS データソースを使用する方法 WAS上で稼動させる場合には、Spring フレームワークによるリソース管理ではなく、 WAS が提供するリソース管理を使用することを推奨 Spring bean 定義ファイル <bean id="WASDataSource" <bean id="WASDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/springDS"/> <property name="jndiName" value="java:comp/env/jdbc/springDS"/> <property name="lookupOnStartup" value="false"/> <property name="lookupOnStartup" value="false"/> <property name="cache" value="true"/> <property name="cache" value="true"/> <property name="proxyInterface" value="javax.sql.DataSource"/> <property name="proxyInterface" value="javax.sql.DataSource"/> </bean> </bean> デプロイメント記述子 <resource-ref> <resource-ref> <res-ref-name>jdbc/springDS</res-ref-name> <res-ref-name>jdbc/springDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </resource-ref> 60 WAS × Webフレームワーク連携手法 デプロイ時にDD上のリソース参照と WAS上のデータソースをマップ Naming Service DataSource JNDI名: jdbc/Sample “Sample” データベース 2008 IBM Japan Systems Engineering Co., Ltd. Spring と WAS トランザクション管理との連携 Spring 2.1 RC1 以降 かつ WAS V6.0.2.19 / WAS V6.1.0.9 以降の場合: – Springが提供する”WebSphereUOWTransactionManager”をトランザクションマネージャーとして使用する(これは内部 的にはWASの提供するUOWManagerインターフェースを使用している) – これによりSpringが提供する宣言的トランザクション(6つのトランザクション属性すべて)をWASランタイムからサポートでき るようになり、Springによるトランザクションの中断および再開が可能となる Spring bean定義ファイル <bean <bean id="transactionManager" id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/> class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/> ... ... </bean> </bean> <bean <bean id="someBean" id="someBean" class="some.class"> class="some.class"> <property <property name="transactionManager" name="transactionManager" >> <ref <ref bean="transactionManager"/> bean="transactionManager"/> </property> </property> ... ... </bean> </bean> <property <property name="transactionAttributes"> name="transactionAttributes"> <props> <props> <prop <prop key="*">PROPAGATION_REQUIRED</prop> key="*">PROPAGATION_REQUIRED</prop> </props> </props> </property> </property> WebSphereUOWTransactionManagerを使 用することにより、Springが提供する以下の6 つのトランザクション属性すべてをサポート • PROPAGATION_REQUIRED • PROPAGATION_SUPPORTS • PROPAGATION_MANDATORY • PROPAGATION_REQUIRES_NEW • PROPAGATION_NOT_SUPPORTED • PROPAGATION_NEVER Spring 2.1 RC1 より前、または、WAS V6.0.2.19 および WAS V6.1.0.9 より前 の場合: – Springによるトランザクションの中断および再開はサポートできない – Springが提供する”JtaTransactionManager”というパッケージを使い、WASからサポートできない「Springによるトランザ クションの中断および再開」を使わないように構成する必要がある(通常のUserTransactionとして構成する) – Springは”WebSphereTransactionManagerFactoryBean” というWAS用パッケージも提供しているが、こちらはサポー トされないWASの内部インターフェースを利用しているため使ってはいけない JtaTransactionManagerを使用することも可能。た Spring bean定義ファイル <bean <bean id="transactionManager" id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> class="org.springframework.transaction.jta.JtaTransactionManager"> <property <property name="autodetectTransactionManager“ name="autodetectTransactionManager“ value="false" value="false" /> /> </bean> </bean> 61 Presentation Title | Presentation Subtitle だし、この場合、autodetectTransactionManager を false とすることで、Springのトランザクション属性 を以下の4つに限定する必要がある。 • PROPAGATION_REQUIRED • PROPAGATION_SUPPORTS • PROPAGATION_MANDATORY 2008 IBM Japan Systems Engineering Co., Ltd. • PROPAGATION_NEVER (補足)トランザクション属性について 属性 内容 Required 呼び出し元でトランザクションを開始していいない場合、呼び出し先で新規トランザクションを開始する 呼び出し元でトランザクションを開始している場合、その既存トランザクションの中で呼び出し先のメソッドが実行される Mandatory 呼び出し元でトランザクションを開始していいない場合、例外が発生する 呼び出し元でトランザクションを開始している場合、その既存トランザクションの中で呼び出し先のメソッドが実行される RequiresNew 呼び出し元でトランザクションを開始していいない場合、呼び出し先で新規トランザクションを開始する 呼び出し元でトランザクションを開始している場合、その既存トランザクションを一時停止して、呼び出し先で新規トランザクションを開始する NotSupported 呼び出し元でトランザクションを開始していいない場合、呼び出し先ではトランザクションを使用しない 呼び出し元でトランザクションを開始している場合、その既存トランザクションを一時停止しますが、呼び出し先ではトランザクションを開始しません Supports 呼び出し元がトランザクションを開始していない場合、呼び出し先ではトランザクションを使用しない 呼び出し元がトランザクションを開始している場合、その既存トランザクションの中で呼び出し先のメソッドが実行される Never 呼び出し元がトランザクションを開始していない場合、呼び出し先ではトランザクションを使用しない 呼び出し元がトランザクションを開始している場合、例外が発生する ◆ 呼び出し元で トランザクションが開始されていない 呼び出し元 RequiredNew RequiredNew Mandatory Mandatory Required Required 呼び出し先 ◆ 呼び出し元で トランザクションが開始されていない 呼び出し先 呼び出し元 NotSupported NotSupported ◆ 呼び出し元で トランザクションが開始されていない 呼び出し先 呼び出し元 トランザクション の中断と再開が入る ◆ 呼び出し元で トランザクションが開始されていない 呼び出し元 呼び出し先 例外 メソッドABC() メソッドXYZ(){ メソッドABC() } 呼び出し元 呼び出し先 ◆ 呼び出し元で トランザクションが開始されている 呼び出し元 トランザクションに 参加 ◆ 呼び出し元で トランザクションが開始されている 呼び出し元 呼び出し先 トランザクションに 参加 WAS × Webフレームワーク連携手法 トランザクションを 開始しない ◆ 呼び出し元で トランザクションが開始されている 呼び出し元 メソッドXYZ(){ メソッドABC() } 呼び出し先 メソッドXYZ(){ メソッドABC() } } 新規トランザクションを 開始 呼び出し元がロールバックしても 呼び出し先はロールバックしない メソッドXYZ(){ } トランザクションを 開始 メソッドXYZ(){ メソッドABC() } 62 呼び出し先 メソッドABC() } 例外が投げられる メソッドXYZ(){ メソッドABC() メソッドXYZ(){ メソッドABC() } トランザクションを 開始 ◆ 呼び出し元で トランザクションが開始されている メソッドXYZ(){ トランザクションに 参加しない 2008 IBM Japan Systems Engineering Co., Ltd. (補足)JTAで提供されているトランザクション機能 ① ② ③ 1. UserTransactionインターフェース – ユーザー・アプリケーションが直接トランザクションを制御する際に利用 – トランザクションの開始、Commit/Rollbackなどを行うことができる 2. TransactionManagerインターフェース – EJBコンテナーなどがトランザクションの制御を行うために利用するAPI – 直接アプリケーション開発者が利用することを意図してデザインされていない – TransactionManagerインターフェースが提供する機能の中には、トランザクションのsuspend/resumeの機能など UserTransactionインターフェースでは提供されていないものがいくつかある – これにより現在実行中のトランザクションを一時停止して別のトランザクションを開始することが可能、つまりネストした (入れ子になった)トランザクションを実現できる(EJBのトランザクション属性へRequiresNewを指定したケースに相当) 3. XAResourceインターフェース – トランザクションマネージャーがデータベースやメッセージングシステムなどのリソースマネージャーを操作するために利用 63 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. (補足)UOWManagerインターフェースについて(1) WASのV6.0.2.19およびV6.1.0.9以降から提供されているインターフェース アプリケーションからWASのTransactionManagerの安全な制御を可能にする – TransactionManagerインターフェースは、EJBコンテナでのみ使用がサポートされており、アプリケーションから利用することはサポート対象外だった 通常のUserTransactionインターフェースでは提供されていないトランザクション管理機能が使用可能となる – トランザクションのsuspend/resume機能など、NotSupportedやRequiredNewというトランザクション属性が指定できる Spring 2.1 RC1から提供された“WebSphereUOWTransactionManager”は内部的に”UOWManager”を使用 して実装しており、SpringBeanのトランザクション制御をWASランタイムへ委任することを可能とする UOWManagerを使用したコーディング例 UOWManagerをJNDIでlookupして取得 Context ic = new InitialContext(); Context ic = new InitialContext(); UOWManager uowmgr UOWManager uowmgr = (UOWManager) ic.lookup("java:comp/websphere/UOWManager"); = (UOWManager) ic.lookup("java:comp/websphere/UOWManager"); ... ... try { try { uowmgr.runUnderUOW( uowmgr.runUnderUOW( UOW_TYPE_GLOBAL_TRANSACTION, UOW_TYPE_GLOBAL_TRANSACTION, false, false, new UOWAction() { new UOWAction() { public void run() throws Exception { public void run() throws Exception { << ここにトランザクション処理を記述する >> << ここにトランザクション処理を記述する >> } } }); }); } catch (UOWActionException e) { } catch (UOWActionException e) { // 処理でチェック例外が発生 // 処理でチェック例外が発生 } UserTx1 Application } begin() runUnderUOW() UOWManagerインターフェースのrunUnderUOW()メソッドによりトランザクション・コンテキストを設定 (1)トランザクションのタイプを指定 - UOW_TYPE_GLOBAL_TRANSACTION : グローバル・トランザクション - UOW_TYPE_LOCAL_TRANSACTION : ローカル・トランザクション - UOW_TYPE_ACTIVITYSESSION : ActivitySession (WAS独自のトランザクション・タイプ) (2)同一種類のトランザクション・タイプが実行されていた場合にどうするか - true :既存トランザクションを引き継ぐ - false : 新規トランザクションを開始する なお、違う種類のトランザクション・タイプが実行されている場合には、 一時停止して、新規トランザクションを開始します (3)実行するトランザクション処理をUOWActionメソッド内に記述 TransactionManager UOWManager UOWAction UserTx2 トランザクション1 run () begin() commit() トランザクション2 commit() 64 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. (補足)UOWManagerインターフェースについて(2) UOWManagerインターフェースは、UOWSynchronizationRegistry インターフェースをExtendsしており、 JTA1.1で提供されるTransactionSynchronizationRegisitryインターフェースと同等の機能を提供 – JTA1.1はJava EE 5の仕様の一部 – 現在実行中のトランザクション・コンテキストにリソースをマップする機能、フレームワークなどがトランザクションの同期をおこなうための機能などを提供 – トランザクションマネージャーが管理するトランザクションと、直接管理できないリソース(XAでないリソース)の同期をとることが可能となる UOWManagerを使用したトランザクション同期処理の例 UOWManagerをJNDIでlookupして取得 UOWSynchronizationRegistryを取得してもよい Context ic = new InitialContext(); Context ic = new InitialContext(); UOWManager uowmgr = (UOWManager) ic.lookup("java:comp/websphere/UOWManager"); UOWManager uowmgr = (UOWManager) ic.lookup("java:comp/websphere/UOWManager"); //UOWManager uowsr = (UOWSynchronizationRegistry) ic.lookup("java:comp/websphere/UOWSynchronizationRegistry"); //UOWManager uowsr = (UOWSynchronizationRegistry) ic.lookup("java:comp/websphere/UOWSynchronizationRegistry"); ... ... uowmgr.registerInterposedSynchronization( uowmgr.registerInterposedSynchronization( new Synchronization() { new Synchronization() { public void beforeCompletion() { registerInterposedSynchronization()メソッドの引数へSynchronizationを実装したインスタンスを渡す。 public void beforeCompletion() { // 2-Phase Commitの前に行う処理 beforeCompletion()メソッドにxa_prepareに相当する処理を,afterCompletion()メソッドに引数に応じ // 2-Phase Commitの前に行う処理 } てCommit/Rollback (xa_commit)に相当する処理を記述することにより、トランザクション中で処理さ } public void afterCompletion(int status) れるリソースと同期して、リソースを更新することが可能となります public void afterCompletion(int status) // 2-Phase Commitの後に行う処理 // 2-Phase Commitの後に行う処理 } } } } ); ); TransactionManager Application UserTx begin() UOWManager Synchronization new reigisterInterposedSynchronization() commit() beforeCompletion() afterCompletion() 65 WAS × Webフレームワーク連携手法 複数RMへの DB更新処理 Resouce Manager (non XA) xa_prepare() Resouce Manager (XA) Resouce xa_commit() Manager (XA) 2008 IBM Japan Systems Engineering Co., Ltd. SpringとWASのスケジューリング機能の連携 スケジューリング機能には”WorkManagerTaskExecutor”クラスを使用すること – Springにはスケジューリング機能(非同期プログラミング)を実現するパッケージ(TaskExecutorクラス)は、 WASでサポートされるもの(SpringからWASへスレッド管理を委任できるもの)は、CommonJ WorkManagerを利用するWorkManagerTaskExecutorパッケージのみ – それ以外のSpringスケジューリング・パッケージ(java.util.timer、quartz、backportconcurrentなどをサ ポートするパッケージ)は、WAS(コンテナー)が管理できないスレッドを生成するため使用してはいけない Spring bean定義ファイル <bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> <bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> <property name="workManagerName" value=“java:comp/env/wm/MyWorkManager"/> <property name="workManagerName" value=“java:comp/env/wm/MyWorkManager"/> <property name="resourceRef" value=“true"/> <property name="resourceRef" value=“true"/> </bean> </bean> デプロイ時にDD上のリソース参照と WAS上のWorkManagerリソースをマップ デプロイメント記述子 <resource-ref> <resource-ref> <res-ref-name>wm/MyWorkManager</res-ref-name> <res-ref-name>wm/MyWorkManager</res-ref-name> <res-type>commonj.work.WorkManager</res-type> <res-type>commonj.work.WorkManager</res-type> <res-auth>Container</res-auth> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </resource-ref> 66 WAS × Webフレームワーク連携手法 Naming Service WorkManager JNDI名: wm/MyWorkManger 2008 IBM Japan Systems Engineering Co., Ltd. (参考)非管理スレッドについての注意点 WASから管理されないスレッド(非管理スレッド)を使用してはいけない理由 – 非管理スレッドはJava EE コンテキスト情報にアクセスできない – WASが提供するセキュリティ制御、トランザクション管理、高可用性といったメリットを享受でき なくなる – WAS管理外で(コンテナーによるスレッドなどのリソース制御の外で)、リソースが勝手に使われる ことになる – パフォーマンス管理に影響が出る要因となる – WASのグレースフル・シャットダウン、リソース障害からの回復を遅らせる要因ともなる 67 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. クラスローダー設定に関しての考慮点 WASのクラスロード設定を適切なものに変更する必要がある – WASは内部的にオープンソース・フレームワーク(Jakarta Commons Loggingなど)をライブラリとして利用 しているが、Springなどのフレームワークが依存するライブラリとバージョンが異なる – WASデフォルト設定のままでは、WAS内部ライブラリが先に参照されるため、クラスローダー設定を適切に する必要がある – クラスローダー設定の問題がある場合には、ログに「クラスのバージョン不一致」(ClassCastException、 java.lang.VerifyErrorsなど)が出力される クラスローダーの問題を回避するための設定 アプリケーション・レベルのクラス・ローダー設定 – 以下の手順にて設定変更を実施 1. 依存するライブラリをアプリケーションの一部として、 EAR最上位とwarモジュールのWEB-INF/lib配下に配置し、 2. アプリケーションのクラスローダー順序の設定を 「PARENT_LAST(親が最後)」に変更する (アプリケーション・サーバーのレベルで変更してもよい) サーバー・レベルのクラス・ローダー設定 – なお、WAS6.1以降であれば、アプリケーション・サーバーの設定において、 WAS内部クラスへアクセスさせない設定(可視制限モードを有効)とする ことも有効である 68 WAS × Webフレームワーク連携手法 可視制限モード設定 2008 IBM Japan Systems Engineering Co., Ltd. (補足)WASのクラスローダー設定について クラス・ローダーの階層構造 クラス・ローダー設定による違い アプリケーション・クラスローダー 複数 (デフォルト) WAR・ クラス ロー ダー モジュール (default) EAR 1 アプリケーション ・クラスローダー EAR 2 アプリケーション ・クラスローダー E1.jar, Util1.jar E2.jar, Util2.jar WAR 1A クラスローダー W1A.war WAR 1B クラスローダー W1B.war アプリケーション・サーバー 関連付け共用ライブラリ アプリケー ション <EAR_ROOT>以下配置ライブラリ アプリケーション関連付け共用ライブラリ 単一 WAR 2A クラスローダー W2A.war すべてのEAR アプリケーション・クラスローダー E1.jar, Util1.jar, E2.jar, Util2.jar WAR 1A WAR 1B クラスローダー クラスローダー W1A.war W1B.war WAR 2A クラスローダー W2A.war EAR 1 アプリケーション ・クラスローダー EAR 2 アプリケーション ・クラスローダー すべてのEAR アプリケーション・クラスローダー E1.jar, Util1.jar E2.jar, Util2.jar E1.jar, Util1.jar, E2.jar, Util2.jar W1A.war, W1B.war W2A.war W1A.war, W1B.war, W2A.war <WAR_ROOT>¥WEB-INF¥lib以下 に配置されるライブラリ 69 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. WAS データソースを Hibernate から利用する設定 Hibernate 構成ファイルにて ” hibernate.connection.datasource”プロパティを設定することで、 WAS データソースを利用することが可能となる – これにより WAS ランタイムが提供する接続プール、トランザクション管理、分離レベル設定を利用できるというメリットがある なお、Spring と Hibernate を同時に使用して連携させる場合には、Spring Bean 定義ファイルにて WAS データソース設定を実施することにより、Hibernate 構成ファイルでの設定は不要とすることも 可能 Hibernate 構成ファイル <session-factory> <session-factory> … … <property name=“hibernate.connection.datasource” > <property name=“hibernate.connection.datasource” > java:comp/env/jdbc/hibernateds java:comp/env/jdbc/hibernateds </property> … </property> … <session-factory> <session-factory> デプロイメント記述子 <resource-ref> <resource-ref> <res-ref-name>jdbc/hibernateds</res-ref-name> <res-ref-name>jdbc/hibernateds</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </resource-ref> 70 WAS × Webフレームワーク連携手法 デプロイ時にDD上のリソース参照と WAS上のデータソースをマップ Naming Service DataSource JNDI名: jdbc/Sample “Sample” Database 2008 IBM Japan Systems Engineering Co., Ltd. Hibernate と WAS トランザクション管理との連携 Hibernate 構成ファイルへ以下の2つのプロパティを設定することで、HibernateとWASのトランザクションを連 携することが可能となる – hibernate.transaction.factory_class : トランザクション制御を定義 – hibernate.transaction.manager_lookup_class : トランザクション同期の登録メカニズムを定義 トランザクション制御は「コンテナー管理トランザクション(CMT)」と「Bean管理トランザクション (UserTransaction)」の両方が使用できる Hibernate構成ファイル(コンテナー管理トランザクションの場合) <property name="hibernate.transaction.factory_class"> <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.CMTTransactionFactory org.hibernate.transaction.CMTTransactionFactory </property> </property> <property name="hibernate.transaction.manager_lookup_class"> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.WebSphereExtendedJTATransactionLookup org.hibernate.transaction.WebSphereExtendedJTATransactionLookup </property> </property> Hibernate構成ファイル(Bean管理トランザクションの場合) <property name="hibernate.transaction.factory_class"> <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory org.hibernate.transaction.JTATransactionFactory </property> </property> <property name="hibernate.transaction.manager_lookup_class"> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.WebSphereExtendedJTATransactionLookup org.hibernate.transaction.WebSphereExtendedJTATransactionLookup </property> </property> <property name="jta.UserTransaction"> <property name="jta.UserTransaction"> java:comp/UserTransaction java:comp/UserTransaction </property > </property > hibernate.transaction.factory_classプロパティによりトランザク ション制御を定義する。 • コンテナー管理トランザクションの場合には CMTTransactionFactory • Bean管理トランザクションの場合には JTATransactionFactory を設定する。 hibernate.transaction.manager_lookup_classプロパ ティによりトランザクション同期の登録メカニズムを定義す る。CMT、UserTransactionの両方とも同じプロパティ WebSphereExtendedJTATransactionLookupを設 定する。これによりWASランタイムと連携することが可能 となる。 Bean管理トランザクションの場合にのみ、 jta.UserTransaction プロパティにて、WASランタイムより 取得するトランザクションのJNDI名を指定する。 ただし、上記のトランザクション構成は、WAS V4 および V5 では使用できない点に注意! 71 – ExtendedJTATransactionLookupプロパティーがJTA1.1仕様のExtendedJTATransactionインターフェースに依存しており、このインターフェースが サポートされるのは WAS V6.x 以降(WBISF であれば V5.1 以降)であるため – なお、Hibernateが他にもトランザクション構成用プロパティを提供していますが、WAS内部インターフェースを使用するものもあり、上記以外め推奨され ません WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. (補足)ExtendedJTATransaction インターフェース JTA1.1仕様に定義されている“拡張JTA”と呼ばれるインターフェース WAS V6.x 以降(WBISF であれば V5.1)からサポートされる このインターフェースを使用することで、グローバル・トランザクションID、ローカ ル・トランザクションID へのアクセスを提供する – これによりUserTransactionを使用するアプリ側で、TM(WAS)から割り振られたグローバル・トラン ザクションID/ ローカル・トランザクションIDを確認できる 参考資料 – InfoCenter - 「拡張JTAサポート」 http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.base.doc/info/ae s/ae/cjta_extjta.html – InfoCenter - 「ExtendedJTATransaction」 http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.javadoc.doc/publi c_html/api/com/ibm/websphere/jtaextensions/ExtendedJTATransaction.html 72 WAS × Webフレームワーク連携手法 2008 IBM Japan Systems Engineering Co., Ltd. 分離レベルを複数設定するには? ~HibernateでWASデータソース(共有可能接続)を使用した際の考慮点 WASデータソースを共有可能接続と設定する場合、複数の分離レベルを設定できず、SharingViolationが発生 – Hibernate構成ファイルにてhibernate.connection.isolationプロパティを設定していても、分離レベルを変更することはできない それでは複数の分離レベルをサポートしたい場合には? – 共用接続(Shareable)をやめて、非共用接続(Unshareable)に変更する – 「Hibernateセッション・ファクトリー」と「データソースのリソース参照」を複数定義し、それぞれを個別にマップする Hibernateセッション・ファクトリーとリソース参照を複数定義することで、複数の分離レベルをサポート デプロイ時にリソース参照と WASデータソースをマップ Hibernate構成ファイル <session-factory> <session-factory> … … <property name=“hibernate.connection.datasource” > <property name=“hibernate.connection.datasource” > java:comp/env/jdbc/hibernateDS01 java:comp/env/jdbc/hibernateDS01 </property> </property> <property name=“hibernate.connection.isolation” > 1 </property> <property name=“hibernate.connection.isolation” > 1 </property> … … <session-factory> <session-factory> … … <session-factory> <session-factory> … … <property name=“hibernate.connection.datasource” > <property name=“hibernate.connection.datasource” > java:comp/env/jdbc/hibernateDS02 java:comp/env/jdbc/hibernateDS02 </property> </property> <property name=“hibernate.connection.isolation” > 2 </property> <property name=“hibernate.connection.isolation” > 2 </property> … … <session-factory> <session-factory> 73 デプロイメント記述子 <resource-ref> <resource-ref> <res-ref-name>jdbc/hibernateDS01</res-ref-name> <res-ref-name>jdbc/hibernateDS01</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-auth>Container</res-auth> <res-sharing-scope>Unshareable</res-sharing-scope> <res-sharing-scope>Unshareable</res-sharing-scope> </resource-ref> </resource-ref> … … <resource-ref> <resource-ref> <res-ref-name>jdbc/hibernateDS02</res-ref-name> <res-ref-name>jdbc/hibernateDS02</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-auth>Container</res-auth> <res-sharing-scope>Unshareable</res-sharing-scope> <res-sharing-scope>Unshareable</res-sharing-scope> </resource-ref> </resource-ref> hibernate.connection.isolationプロパティで「分離レベル」を設定 1: ReadUncommitted (非コミット読み取り) 2: ReadCommitted (カーソル固定に相当) 4: RepeatableRead (読み取り固定に相当) 8: Serializable (反復可能読み取りに相当) WAS × Webフレームワーク連携手法 Naming Service DataSource JNDI名: jdbc/Sample “Sample” Database 2008 IBM Japan Systems Engineering Co., Ltd. (補足)分離レベルについて JDBCでは、トランザクションの分離レベルが4種類定義 この分離レベルはDB2の分離レベルとは異なるので注意が必要 – JDBCのデフォルトの分離レベルはRR – DB2のデフォルトの分離レベルはCS JDBC ISO分離レベル DB2 TRANSACTION_READ_UNCOMMITED ( カスタム・プロパティ int値 1 ) RU Read Uncommited 非コミット読み取り UR Uncommited Read TRANSACTION_READ_COMMITED ( カスタム・プロパティ int値 2 ) RC Read Commited カーソル固定 CS Cursor Stability TRANSACTION_REPEATABLE_READ ( カスタム・プロパティ int値 4 ) RR Repeatable Read 読み取り固定 RS Read Stability S Serializable 反復可能読み取り RR Repeatable Read TRANSACTION_SERIALIZABLE ( カスタム・プロパティ int値 8 ) アプリケーションからは以下を意識して設定 「一度参照した照会結果に対して、どの程度変更を許容するか」 「どの程度変更を許容するか」とは? ISO分離レベル 74 どの程度の変更を許容するか Read Uncommited 一度参照したレコードが、無かったことになってもよい Read Commited コミット済みのレコードだけを参照したい → 一度参照したレコードが変更されてもよい Repeatable Read 参照したレコードは、更新されたくない → 読み直したときに、同じレコードが欲しい Serializable 読み直したときに、追加のレコードが増えるのもイヤだ Presentation Title | Presentation Subtitle 2008 IBM Japan Systems Engineering Co., Ltd. 参考資料 WebSphere Application Server 最新動向ワークショップ(2007年4月版) http://www-06.ibm.com/jp/software/websphere/developer/was/wv61/workshop/ – 「OpenSource(Spring Framework)」および「OpenSource(O/R Mapping)」のセッションを参照 Using Spring and Hibernate with WebSphere Application Server http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html Seasar2: 第 2 回 UOWManager によるトランザクションの制御 https://www.ibm.com/developerworks/jp/java/library/j_j-seasar02/ 75 Presentation Title | Presentation Subtitle 2008 IBM Japan Systems Engineering Co., Ltd.