Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

java - Implementing a wormhole pattern using AspectJ

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 

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

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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.

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.

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...