pointcut に関して高い記述力を持つ アスペクト指向言語 Josh 東京工業大学 中川 清志 千葉 滋 SPA 2003, Hakone 1 アスペクト指向(AOP) オブジェクト指向の限界 ある種の処理は複数クラスに散らばる ロギング、同期、永続性などの処理 アスペクト指向の利点 そのような処理をアスペクトとしてモジュール化 クラスとアスペクトは分離して記述 オブジェクト指向を補完 SPA 2003, Hakone 2 AOPの利用例:[ロギング] 従来は アプリケーション内にロギング コードを記述 ログ出力のタイミングや方式 が変わるとアプリケーション のコードの変更も必要 class Log { static void print(String msg) { System.out.println(msg); } } class Car extends Vehicle { void start() { Log.print(“start Car”); ... } void back() { Log.print(“back Car”); } } class Bike extends Vehicle{ void start() { Log.print(“start Bike”); ... } } SPA 2003, Hakone 3 AOPの利用例:[ロギング] AOPでは アプリケーションと分離して記述 アスペクト : メソッド実行前には Log クラス の print()を呼べ! class Log { static void print(String msg) { System.out.println(msg); } } class Car extends Vehicle { void start() { 必要なし Log.print(“start Car”); ... } void back() { 必要なし Log.print(“back Car”); } } class Bike extends Vehicle{ void start() { Log.print(“start Bike”);必要なし ... } } SPA 2003, Hakone 4 合成処理 weave アスペクトを各クラスに埋め込む処理 アスペクトは以下の2つを指定 1. どこに埋め込むか (pointcut) 2. 何のコードを埋め込むか(アドバイス) クラス アスペクト 本研究は前者の pointcut に注目したものである SPA 2003, Hakone 5 pointcut のメカニズム 条件に応じた join-point の抽出 join-point とはプログラム中の個々の演算 メソッド呼び出し、フィールド参照、インスタンス生成など 例 : call(void Point.setX(int)) [AspectJ*の文法] call は pointcut指定子の一つ メソッド呼び出し join-point の抽出 カッコ内は条件 void型、Pointクラス、setXという名前、 int型の引数を一つ持つ * Kiczales等 ECOOP1997 SPA 2003, Hakone 6 pointcut の記述力が高い AOP言語 Josh Java で新しい pointcut指定子を定義可能 強力な pointcut が可能 既存言語では組み込み指定子に限定 記述できない 複雑な pointcut の存在 汎用的な指定子は組み込みで提供 複雑な pointcut指定子のみ定義すればよい SPA 2003, Hakone 7 複雑なpointcut例 : 排他制御 マルチスレッドにおいて、フィールド‘balance’ の一貫性を保持したい 解決方法: class BankAccount { ここでフィールドの int balance; public void withdraw(int bal){ if (balance < bal) 「balanceにアクセス 値を調べても している全メソッド」 をsynchronizedにする throw new BankException(); しかしながら, 「balanceにアクセスしている 全メソッド」という条件の pointcutを記述できない } } balance -= bal; この命令の前に値が変 えられてるかもしれない SPA 2003, Hakone 8 Josh weaver クラス内の各コードを全てチェック 1. join-point の発見 アスペクト埋め込みの ターゲットクラス 表 : 発見対象の join-point 一覧 2. join-point オブジェクトを渡す 3. pointcut に該当するかの決定 4. アドバイス埋め込み MethodCall フィールド参照 FieldAccess インスタンス生成 NewExpr Cast instanceof 式 Instanceof 4 weaver 3 メソッド呼び出し キャスト式 1 2 アスペクト SPA 2003, Hakone 9 pointcut 指定子の定義(1/2) boolean 型のメソッドで定義 第一引数 : 対象とする /* pointcut メソッドの定義例*/ join-point オブジェクト static boolean simpleCall weaver から受け取る メソッド呼び出し MethodCall フィールド参照 FieldAccess インスタンス生成 NewExpr キャスト式 Cast instanceof 式 Instanceof } (MethodCall m,String name){ String name2 = m.getMethodName(); if (name.equals(name2)) return true; else return false; SPA 2003, Hakone 10 pointcut 指定子の定義(2/2) join-point の情報を入手可能 名前、属するクラス、型など 例 : MethodCall クラス getMethodName(), getClassName() メタオブジェクトの操作 getMethod()でメソッドの メタオブジェクト 深い情報を得られる /* pointcut メソッドの定義例*/ static boolean simpleCall (MethodCall m,String name){ String name2 = m.getMethodName(); if (name.equals(name2)) return true; else return false; } SPA 2003, Hakone 11 Josh アスペクト 全体のコード アスペクトの宣言 通常のJava要素 pointcut 指定子の 定義 pointcut の使用 & アドバイス aspect LogAspect { static int count = 0; static void log() { System.out.println (“callhello” + (count++)); } static boolean simpleCall (MethodCall m, String name) { /* 省略 */ } before : LogAspect.simpleCall(“hello”) { LogAspect.log(); } join-pointオブジェクト } の実引数は必要ない SPA 2003, Hakone 12 Josh実行までの概観 .josh 独自言語で書いた アスペクト コード変換 .class Java の要素 .class アスペクト埋め込みの ターゲット weave .class pointcut 指定子の定義 pointcut の使用 & アドバイス SPA 2003, Hakone .class アスペクトとクラス の両方の機能 JVM 13 コード変換 独自文法のアスペクトを Javaコードに変換 simpleCall の対象 join-point は MethodCall before : simpleCall(“hello”) { System.out.println(“-hello is called-”); } コード変換 引数 ‘m’ はWeaver から渡される join-pointオブジェクト replace はjoin-pointの コードを変える(アドバイス) public void edit(MethodCall m) { if (simpleCall(m, “hello”)) { m.replace (“Sysetem.out.println(\”-hello is called-\”); $_ = $proceed($$);”); } } SPA 2003, Hakone 14 weaver のコード CtClass, CtMethod : public void weave(CtClass target, ExprEditor editor){ ExprEditor : クラス、メソッドを表す メタオブジェクト CtMethod[] methods = target.getDeclaredMethods(); pointcut & アドバイスを 持つ Java コード for (int i=0; i < methods.length; i++) instrument(editor) : メソッドの中身を editorで走査、改変 methods[i].instrument(editor); } target.writeFile(); SPA 2003, Hakone 15 「join-pointの実行時情報」引き渡し 例えばメソッド呼び出しターゲットの、インスタンスの情報 AspectJ では pointcut 命令内に記述 target (p) Josh では /* AspectJ での引き渡し*/ before(Point p) : call(void Point.*()) && target(p) { String targetObj = p.toString(); System.out.println(targetObj); } 明記する必要なし ドル記号‘$’で始まる予約語 /* Josh での引き渡し*/ $0 : before : join-point の動作の対象 LogAspect.simpleCall(“hello”) { String targetObj = $0.toString(); となっているオブジェクト System.out.println(targetObj); $1, $2, ... } $r SPA 2003, Hakone 16 関連研究 アスペクト指向言語 AspectJ Hyper/J Composition Filters pointcut の拡張 Soul/AOP [Brichau等 GPCE2002] pointcutを論理型言語で記述 埋め込むコードはSmalltalkで記述 SPA 2003, Hakone 17 まとめ アスペクト指向言語 Josh を提案 pointcut に関して高い記述力を持つ pointcut 指定子を新たにJavaで定義できる 複雑な pointcut が可能 汎用的なものは組み込みで与える 複雑なものだけを自分で定義すればよい SPA 2003, Hakone 18 SPA 2003, Hakone 19 SPA 2003, Hakone 20 (旧)pointcut 指定子の定義方法 boolean set(FieldAccess f, String type, String dec, String name) { CtField cf = f.getField(); String cf_name = cf.getName(); String cf_type = cf.getType().getName(); String cf_dec = cf.getDeclaringClass.getName(); if (f.isWriter() && cf_name.equals(name) && cf_type.equals(type) && cf_dec.equals(dec)) return true; else return false; } SPA 2003, Hakone 21 従来のAOP言語のpointcutの問題点 組み込み(built-in)のpointcut指定子しか使 用できない 意図した場所にpointcutできない、つまりアスペ クトを埋め込めない場合がある 複雑な条件のpointcutをしたい場合に不十分 メソッドのシグネチャだけでなく、内部動作に対しても 条件を課したいときなど SPA 2003, Hakone 22 Josh実行までの概観 .josh 独自言語で書いた アスペクト .class アスペクト埋め込みの ターゲット .class アスペクトとクラス の両方の機能 コード変換 weave .class Java の要素 SPA 2003, Hakone .class JVM pointcut 指定子の定義 pointcut の使用 & アドバイス 23
© Copyright 2024 ExpyDoc