5

AspectJを使用したワームホールパターンの実装例を探しています(Guice AOPにこれを実装する権限がある場合は興味があります)。

ワームホールを使用すると、基本的に、次のような追加のパラメータをコールフローに沿って渡すことができます。

// say we have
class foo {
   public int m0 int a, int b) {
     return m1(a,b);
   }

   public int m1 int a, int b) {
     return m2(a,b);
   }

   public int m2 int a, int b) {
     return a+b;
   }
}
// and I wanted in a non-invasive manner to pass a third parameter of type
class context {
  String userName;
  long timeCalled;
  String path;
}
// I could use an advise to say print the context information
// to trace what was going on without mucking up my method signatures 

このラムニヴァス・ラダッドは、彼の著書AspectJinActionにそのような例があると思います。

前もって感謝します。

4

3 に答える 3

4

実際、 AspectJinActionに例があります。目次を見ると、12.2章が探しているものであることがわかります。その本を買うのは良い考えだろう。暖かくお勧めできます。本の一部をコピーして貼り付けるだけでよいかどうかわからないため、ここでテンプレートを引用します。

public aspect WormholeAspect {
    pointcut callerSpace(<caller context>) :
        <caller pointcut>;

    pointcut calleeSpace(<callee context>) :
        <callee pointcut>;

    pointcut wormhole(<caller context>, <callee context>) :
        cflow(callerSpace(<caller context>)) && 
        calleeSpace(<callee context>);

    // advice to wormhole
    before(<caller context>, <callee context>) :
        wormhole(<caller context>, <callee context>)
    {
            ... advice body
    }
}

TheServerSide.comにLaddadによる古い記事があり、より具体的な例が示されています。それは本からのものと同じではありませんが、似ています。

ご覧のとおり、ポイントカットがあるため、AspectJで簡単に実行できますcflow()。Guiceを使用したことはありませんが、AOPの紹介ページには、Guiceの実装がAOPAlliance仕様の一部であると記載れています。AOP Alliance APIを見ると、ポイントカットのように見えるものはありませんcflow()。コンストラクターとメソッドの呼び出しに加えて、フィールドアクセスがすべてです。

では、すべてのレイヤーでパラメーターを通過させたくない場合は、Spring(AspectJなし)またはGuiceで何ができますか?明らかな解決策はThreadLocal、呼び出し元によって宣言および管理された(つまり、割り当てられたがクリアされた)変数であり、呼び出し先によってアクセスされます。これは良くありません。APIを肥大化させないための回避策にすぎません。ただし、発信者と着信者の両方が、何をどのように共有したいかについて共通の理解を持っている必要があります。ある意味で、そのような実装はパターンというよりはアンチパターンです。可能であれば、AspectJを使用して、これをクリーンでモジュール式の方法で解決し、対処すべき懸念事項を1つのモジュール(アスペクト)にカプセル化します。

于 2012-08-26T12:36:07.950 に答える
1

簡単な例。機能を提供するコンテキストオブジェクトとターゲットオブジェクトがあるとします。これは、コンテキストの状態に何らかの形で依存します。

class T {   
    public void foo() {
        System.out.println("T.foo()");
    }
}

class Context {
    public boolean isValid = true;
    public void doStuff() {
        T t = new T();
        t.foo();
    }
}

public class Main { 
    public static void main(String[] args) {
        Context c = new Context();
        c.doStuff();
    }
}

メンバーがに設定されている場合にのみ、のインスタンスがのインスタンスをContext呼び出すことができるようにするアスペクトは、次のようになります。foo()TisValidtrue

public aspect ContextStateValidation {

    pointcut MyContext(Context c) :
        execution(* Context.*()) && this(c);

    pointcut FooCalls(T t) :
        call(* T.foo()) && target(t);

    pointcut FooCallsInMyContext(Context c, T t) :
        cflow(MyContext(c)) && FooCalls(t);

    void around(Context c, T t) : FooCallsInMyContext(c, t) {
        if (c.isValid)
            proceed(c, t);
    }
}
于 2013-10-29T17:48:39.400 に答える
0

ワームホールパターンは使用しないでください...実際、AOPは、本当に必要であると確信している場合にのみ使用してください。それ以外の場合はそのままにしてください。

ワームホールパターンの欠点は、多くのレイヤーをスキップすることです...それはあなたが本当に欲しいものですか?:)

グルツ、

クリストフ

于 2012-12-18T19:26:43.070 に答える