我正在寻找一个使用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
我相信这个Ramnivas Laddad在他的着作“AspectJ in Action”中有这样一个例子.
提前致谢.
解决方法:
确实在AspectJ in Action中有一个例子.如果你看一下table of contents,你会注意到第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上有一个旧的article by Laddad,有一个更具体的例子.它与书中的不同,但相似.
正如您所看到的,在AspectJ中很容易做到,因为您有cflow()切入点.我从未使用过Guice,但其AOP introduction页面提到它们的实现是AOP Alliance规范的一部分.看看AOP Alliance API,没有什么看起来像cflow()切入点,它是围绕构造函数&方法调用加上字段访问.
那么如果你想避免在所有层中通过参数,你可以在Spring(没有AspectJ)或Guice中做什么?显而易见的解决方案是由调用者声明和管理(即分配,但也清除)并由被调用者访问的ThreadLocal变量.这不是很好,只是一种解决方法,以免膨胀API.但它要求来电者和被叫者都对他们想要分享的内容和方式有共同的理解.在某种程度上,这种实现更多的是反模式而不是模式.如果可以的话,使用AspectJ以便以一种干净和模块化的方式解决这个问题,将问题封装在一个模块(方面)中.