使用AspectJ实现虫洞模式 [英] Implementing a wormhole pattern using AspectJ

查看:83
本文介绍了使用AspectJ实现虫洞模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找使用AspectJ进行虫洞模式实现的示例(如果Guice AOP有权实现此功能,我将对此感兴趣.)

I'm looking for an example to a wormhole pattern implementation using AspectJ (would be interested if Guice AOP has the power to implement this).

蠕虫漏洞本质上使您可以沿调用流传递其他参数,例如:

A worm hole essentially allows you to pass additional parameters along the call flow for example:

// 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》一书中有这样的例子.

I believe this Ramnivas Laddad has such an example in his book AspectJ in Action.

谢谢.

推荐答案

实际上在 AspectJ的使用中有一个示例.如果您查看目录,您会发现您正在寻找第12.2章.买书是个好主意.我可以热烈推荐.因为我不确定只复制&粘贴本书的部分内容,我将在此处引用模板:

Indeed there is an example in AspectJ in Action. If you look at the table of contents you notice that chapter 12.2 is what you are looking for. It would be a good idea to buy the book. I can recommend it warmly. Because I am not sure if it is okay to just copy & paste parts of the book, I will just quote the template here:

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

有一本旧的 Article of Laddad 在TheServerSide.com上,还有一个更具体的示例.它与书中的不是同一本书,而是相似的.

There is an old article by Laddad on TheServerSide.com with a more concrete example. It is not the same one from the book, but similar.

如您所见,在AspectJ中很容易做到,因为您有cflow()切入点.我从未使用过Guice,但是它的 AOP简介页提到了它们的实现是 AOP联盟规范的一部分.查看 AOP联盟API ,没有什么看起来像cflow()切入点,到处都是构造函数&方法调用加上字段访问.

As you can see, it is easy to do in AspectJ because there you have the cflow() pointcut. I have never used Guice, but its AOP introduction page mentions that their implementation is part of the AOP Alliance specification. Looking at the AOP Alliance API, there is nothing which looks like a cflow() pointcut, it is all around constructor & method invocation plus field access.

那么,如果要避免在所有层中传递参数,那么在Spring(没有AspectJ)或Guice中怎么办?一个明显的解决方案是ThreadLocal变量,该变量由调用方声明和管理(即已分配但也已清除),并由被调用方访问.这不是很好,只是一种解决方法,以免使API膨胀.但这要求主叫方和被叫方都对要共享的内容以及共享方式有共同的了解.从某种意义上说,这种实现更多是反模式而不是模式.如果可以,请使用AspectJ以便以一种干净的模块化方式解决此问题,将要解决的问题封装在一个模块(方面)中.

So what can you do in Spring (without AspectJ) or Guice if you want to avoid passing through the parameter through all layers? The obvious solution is a ThreadLocal variable declared and managed (i.e. assigned, but also cleared) by the caller and accessed by the callee. This is not nice, only a workaround so as not to bloat the API. But it requires that both caller and callee have a common understanding of what they want to share and how. In a way that kind of implementation is more of an anti-pattern than a pattern. If you can, use AspectJ so as to solve this in a clean and modular way, encapsulating the concern to be addressed in one module (aspect).

这篇关于使用AspectJ实现虫洞模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆