AspectJ - 是否有可能执行建议?

问题描述:

我有一个CachingAspect它使用around建议对正确注释的方法执行一些简单的缓存。现在,我想要做的是特别跟踪缓存和around建议。AspectJ - 是否有可能执行建议?

到目前为止,我可以拦截around建议中的方法调用,但不能建议本身。最终,我想获得around意见建议的方法签名。可能吗?

在此先感谢!

+0

我的回答包含'adviceexecution()',即你可以用它拦截其他方面的建议,就像你在其他评论问。你甚至尝试过吗?无论如何,谢谢你接受我的回答,但我的意图是真的帮助你。更精确地描述你的用例,然后我可以更新我的答案。 – kriegaex 2014-07-05 08:01:11

+0

我刚刚重读你的问题,目的似乎更清晰。我的答案后是否更新过?无论如何,我可以在周末看看它。目前我不在PC附近,我只有一台平板电脑。 – kriegaex 2014-07-05 08:05:52

+0

我很忙,在路上呆了一个多星期,但现在我已经更新了我的答案。检查一下可能的解决方案。 – kriegaex 2014-07-16 15:21:47

你是什么意思

[adviceexecution切入点]的意思是不工作我

对于我来说,工作得很好,像这样:

public aspect MetaAspect { 
    before() : within(DummyAspect) && adviceexecution() { 
     System.out.println("MetaAspect: " + thisJoinPointStaticPart.getSignature()); 
     for (Object arg : thisJoinPoint.getArgs()) 
      System.out.println(" " + arg); 
    } 
} 

从这一点来说,看印刷签名,你应该能够进一步细化从DummyAspect挑选哪些意见,如果有不止一个,他们有不同的签名。


更新:

好吧,你编辑了自己的问题,并指出,你需要确定什么是不只是adviceexecution()也是截获方法的签名。没有100%的解决方案,但是如果你确定你的拦截建议以某种方式引用thisJoinPointStaticPart的方法,JoinPoint.StaticPart的一个实例将被添加到建议自己的签名中,并且可以从你的meta方面访问。下面是一个完整的代码示例:

驱动程序:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
     Application application = new Application(); 
     application.writeProperty("fullName", "John Doe"); 
     application.readProperty("firstName"); 
     application.doSomething(11); 
    } 

    public void writeProperty(String name, String value) {} 
    public String readProperty(String name) { return "foo"; } 
    public void doSomething(int number) {} 
} 

缓存方面:

package de.scrum_master.aspect; 

public aspect CachingAspect { 
    pointcut readMethods(String propertyName) : 
     execution(* *.read*(String)) && args(propertyName); 

    before(String propertyName) : readMethods(propertyName) { 
     System.out.println(
      "[CachingAspect] Read method called for property '" + propertyName + "'" 
     ); 
    } 

    Object around(String propertyName) : readMethods(propertyName) { 
     System.out.println(
      "[CachingAspect] Caching property '" + propertyName + 
      "' in method " + thisJoinPointStaticPart.getSignature() 
     ); 
     return proceed(propertyName); 
    } 
} 

正如你所看到的,有这方面的一点建议。第一个没有访问任何连接点成员,第二个没有。即我们将只能在我们的meta方面找到第二个目标签名。

元方面:

package de.scrum_master.aspect; 

import org.aspectj.lang.JoinPoint.StaticPart; 

public aspect AdviceInterceptor { 
    before() : within(CachingAspect) && adviceexecution() { 
     System.out.println("[AdviceInterceptor] Intercepting " + thisJoinPointStaticPart); 
     boolean foundSignature = false; 
     for (Object arg : thisJoinPoint.getArgs()) { 
      if (arg instanceof StaticPart) { 
       foundSignature = true; 
       StaticPart jpStaticPart = (StaticPart) arg; 
       System.out.println("[AdviceInterceptor] Target method = " + jpStaticPart.getSignature()); 
       break; 
      } 
     } 
     if (!foundSignature) 
      System.out.println("[AdviceInterceptor] Target method cannot be determined from advice signature"); 
    } 
} 

元建议遍历它的参数,以便找到一个JoinPoint.StaticPart类型参数。如果它找到一个,它会打印它的目标签名,否则会在循环后打印一个失败注释。

输出示例:

[AdviceInterceptor] Intercepting adviceexecution(void de.scrum_master.aspect.CachingAspect.before(String)) 
[AdviceInterceptor] Target method cannot be determined from advice signature 
[CachingAspect] Read method called for property 'firstName' 
[AdviceInterceptor] Intercepting adviceexecution(Object de.scrum_master.aspect.CachingAspect.around(String, AroundClosure, JoinPoint.StaticPart)) 
[AdviceInterceptor] Target method = String de.scrum_master.app.Application.readProperty(String) 
[CachingAspect] Caching property 'firstName' in method String de.scrum_master.app.Application.readProperty(String) 

+0

我已经做了,但似乎并没有为我工作.. – janhink 2011-05-18 15:47:32

可以使用thisJoinPoint.getSignature()的建议中得到这样的方法签名:

pointcut tolog1() : execution(* Activity+.*(..)) ; 
before() : tolog1() { 
    String method = thisJoinPoint.getSignature().toShortString(); 

    Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs())); 
} 
+0

是的,这是我在'around'的建议。但是现在我想创建另一个建议来追踪“around”建议本身。我怎么做? – janhink 2011-05-19 15:31:13