我正在寻找一个例子来使用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这样一个例子。
提前致谢。
的确存在一个例子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从而解决这一个干净和模块化的方式,封装在一个模块(方面)中要解决的问题。
一个简单的例子。 想象一下,你有提供的功能,这在某种程度上取决于上下文的状态上下文和目标对象 :
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);
}
}
不要使用虫洞模式。其实,使用AOP只有当你真的确定你需要它,否则离开它。
虫洞模式的缺点是,你跳过了很多层的......是你真正想要的是什么? :)
grtz,
克里斯托夫