Web アプリをユーザー毎に カスタマイズ可能にする AOP

Web アプリをユーザー毎に
カスタマイズ可能にする
AOP フレームワーク
東京工業大学 情報科学科4年
千葉研究室 戸部 敦
ユーザー毎にカスタマイズ可能なWebアプリ
 新しい機能やスタイルを追加
 知識のあるユーザーが高度な機能を組み込める
 他のユーザーとの差をつけられる
 例) FC2 ブログ
 自分だけのページを作成できる
 よく使うコンテンツを配置して利便性を向上
 例) my Rakuten, My Yahoo!
 サイトの集客に影響
カスタマイズの自由度
 Web アプリ開発者が提供
パラメータ
ページのスタイルを変更(色、フォント・サイズ)
プログラム・モジュール
開発者が用意する機能の中から選択
 利用者が自由にカスタマイズ
新しいプログラム・モジュールをアップロードして利用
セキュリティ対策が必要
 どの範囲でサポートするかは状況次第
現状:プラグイン機構の利用
 プラグイン機構
 拡張ポイントを公開
 設定ファイルに拡張ポイントで使われるクラスを記述
 実装コスト
 Web アプリ毎にプラグイン機構を個別に実装する必要があり面倒
 DI コンテナは実装コストを軽減
 コンテナのコーディング規則に従う必要あり
 拡張ポイントの制限
 Web アプリ開発時に決めた拡張ポイント
以外はカスタマイズ不可能
<config>
<Style class=“StyleImpl” />
</config>
String html = webApp.style.table(data);
interface Style {
String table(String[][] data);
}
class StyleImpl impl. Style {
String table(String[][] data) {
...
ユーザー単位のプラグイン機構
 単純なプラグイン機構だけでは実現できない
ユーザー毎に読み込む設定が異なる
一般的な DI コンテナでは提供されない
 例) ユーザー毎にスタイルを変更可能なコード
明示的な切り替えが必要。コードが不自然。
String
String
html html
= webApp.
= webApp.
getStyle(uid)
style.table(data);
.table(data);
Aさん用の設定(uid=“A”)
<config>
<Style class=“StyleImplA” />
</config>
Bさん用の設定(uid=“B”)
<config>
<Style class=“StyleImplB” />
</config>
開発したフレームワーク
 AOP 言語でカスタマイズ部分を記述
 開発時に拡張ポイントを決定する必要がない
 開発中に予期しない部分も拡張可能
 元のソースコードを変えなくて良い
 Per-session weaving
 ユーザー単位のカスタマイズ機構を実現
 セッションを見てユーザー毎に異なるアスペクトを適用
 ユーザーのアスペクトを登録する API
 Web アプリ開発者が利用
AOP (アスペクト指向プログラミング)
 横断的関心事をモジュール化するプログラミング技法
 アスペクト:新しいコードの内容とそれを実行する場所の組
 Weave
 アスペクトを適用して元のコードの挙動を変更すること
 元のソースコードの修正は不要(上書きされる)
 開発時に見落とした拡張ポイントも変更可能
webApp.style.table(data);
class HtmlRenderer {
String table(String[][] data) { ... }
}
weave 後の
weave
出力
名前
カナ
敦
アツシ
滋
シゲル
@Glue class Customizer {
@Around(“{ return HTMLコード; }")
Pointcut pc = Pcd.call(“table(..)”);
}
Per-session weaving の考案
 ユーザー毎に異なるアスペクトを weave
 セッションからユーザーの識別子を取得
 ユーザー毎に異なるクラスローダを使用
 他のユーザーに影響を与えない
 Web アプリでユーザー毎に処理を明示的に分ける必要がない
webApp.
webApp.getStyle(uid)
style
.table(data);
.table(data);
(処理A);
(処理B);
weave
フレームワーク
セッションに応じて
weave するアスペクトを
自動的に振り分ける
Aさんのアスペクト
@Glue class CustomizerA {
@Around(“return (処理A)”)
}
Bさんのアスペクト
@Glue class CustomizerB {
@Around(“return (処理B)”)
}
処理の流れ
1.
2.
3.
予めアスペクトを登録しておく
リクエストを処理するときにセッションを取得
セッションに保存された識別子に応じてアスペクトを weave
サーバー
フレームワーク
Webアプリ
アスペクトを登録
セッションを取得
weave
ロード
weave された
Web アプリを
実行
リ
ク
エ
ス
ト
の
処
理
実装
 フレームワークを開発
 サンプルアプリを作成
他のユーザーに影響を与えないことを確認
実装
Aさんのアスペクトを設定
実装
Aさんのアスペクトを weave した
サンプルページ
実装
Bさんのアスペクトを設定
実装
Bさんのアスペクトを weave した
サンプルページ
フレームワークの構成
 サーバープログラムとして Tomcat を使用
 Java で書かれた Web サーバー
 設定ファイルでフレームワークを有効化
 AOP 言語として GluonJ を採用
 Java 文法内でアスペクトを記述
Web アプリ
フレームワーク
Tomcat
GluonJ
Java
OS
関連研究
 プラグイン機構
 AOP を使用しないカスタマイズ機構
 カスタマイズが予め予測された拡張ポイントに限られる
 Web アプリでユーザー毎に読み込む設定を変更する必要
 Load-time weaving
 クラスをロードする時にアスペクトを weave
 ユーザー毎に異なるアスペクトを weave できない
 Dynamic weaving
 プログラム実行中にアスペクトを weave
 アスペクトによるカスタマイズが制限される
 新たなフィールドやメソッドを追加できない
まとめ
 ユーザー毎にカスタマイズ可能な Web アプリの開発フレー
ムワーク
 AOP 言語の利用
 Per-session weaving の考案
 従来手法
実装コスト大!!
 プラグインを Web アプリ毎に実装する必要
 開発時に決めた拡張ポイント以外はカスタマイズ不可能
 ユーザー毎に明示的に処理を分ける必要
 フレームワークの実装
 サンプルアプリを作成し動作を確認
今後の課題
 パフォーマンスの向上と検証
クラスローダの親子関係を用いる
カスタマイズ不可なクラスは親ローダーでロード
親ローダーは最初のリクエストでのみ作成
キャッシュを使用
訪問者が少ないときに有効
アスペクトの weave によるオーバーヘッドを計測
 セキュリティ対策
サーバー上のファイルを不正に読み込むなど
Java アプレットと同等の対策を取る
おしまい
ご清聴ありがとうございました。
複数アスペクトの weave
 現在は単一のアスペクトのみサポート
登録したアスペクトから他のアスペクトを読み込む場合は
GluonJ の実装に依存
 複数のアスペクトを weave するには?
登録されているアスペクトが
挙動を変更する箇所
登録するアスペクトが
挙動を変更する箇所
 共通部分が存在した場合ユーザーに警告を表示
クラスローダでの効率化
AOP クラスローダ
アスペクトを weave するクラスローダ(現在)
AppLib クラスローダ
AOP クラスローダの親
アスペクトの weave されないクラスをロード
リクエスト毎にロードされるのはアスペクトの
weave されるクラスのみ