...

WAS × Webフレームワーク連携手法 ISE Conf. L-2 2008/06/06

by user

on
Category: Documents
59

views

Report

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.
Fly UP