实现使用AspectJ虫洞图案(Implementing a wormhole pattern us

2019-06-27 09:40发布

我正在寻找一个例子来使用AspectJ虫洞模式实现(有兴趣,如果吉斯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 

我相信这拉姆尼瓦斯·拉达在他的行动书的AspectJ这样一个例子。

提前致谢。

Answer 1:

的确存在一个例子AspectJ的行动 。 如果你看一下表的内容您会发现章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
    }
}

有一个古老的文章Laddad的上TheServerSide.com有更具体的例子。 它不是从书的对象相同,但大同小异。

正如你所看到的,这是很容易的AspectJ做,因为有你有cflow()切入点。 我从来没有使用吉斯,但它的AOP的介绍页提到,他们执行的是部分AOP联盟规范。 纵观AOP联盟API ,没有什么它看起来像一个cflow()切入点,这是各地的构造和方法调用加上现场访问。

那么,你可以在Spring做(没有AspectJ的)或吉斯如果你想避免经过参数通过所有层? 显而易见的解决方案是一个ThreadLocal申报和管理,由主叫方(即,分配,但也被清除)和被叫方访问的变量。 这是不是很好,只有一个解决办法,以便不臃肿的API。 但是,它需要两个主叫方和被叫方有他们想要分享怎么样的共识。 在某种程度上这类型的实现更是一个反模式比模式。 如果可以,用AspectJ从而解决这一个干净和模块化的方式,封装在一个模块(方面)中要解决的问题。



Answer 2:

一个简单的例子。 想象一下,你有提供的功能,这在某种程度上取决于上下文的状态上下文目标对象

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()上的实例T仅如果成员isValid设置为true可能如下方式:

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);
    }
}


Answer 3:

不要使用虫洞模式。其实,使用AOP只有当你真的确定你需要它,否则离开它。

虫洞模式的缺点是,你跳过了很多层的......是你真正想要的是什么? :)

grtz,

克里斯托夫



文章来源: Implementing a wormhole pattern using AspectJ