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

查看:23
本文介绍了使用 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 in Action 中确实有一个例子.如果您查看目录,您会注意到第 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
    }
}

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 Alliance 规范的一部分.查看 AOP Alliance 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天全站免登陆