我有CachingAspect
使用around
建议对正确注释的方法执行一些简单的缓存。现在,我想要做的是跟踪缓存和特别是around
建议。
到目前为止,我能够拦截around
建议中的方法调用,而不是建议本身。最终,我希望获得around
建议所建议的方法的签名。有可能吗?
提前致谢!
答案 0 :(得分:1)
答案 1 :(得分:1)
您可以在建议中使用thisJoinPoint.getSignature()来获取方法签名,如下所示:
pointcut tolog1() : execution(* Activity+.*(..)) ;
before() : tolog1() {
String method = thisJoinPoint.getSignature().toShortString();
Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs()));
}
答案 2 :(得分:1)
你是什么意思
[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
的实例将被添加到建议自己的签名中,并且可以从您的签名中访问元方面。这是一个完整的代码示例:
驱动程序应用程序:
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);
}
}
如您所见,这方面有两点建议。第一个不访问任何连接点成员,第二个成员。即我们将只能在元方面找到第二个目标签名。
元方面:
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)