我在以下示例代码中发现了我的问题。 HelloWorld
类是我的源代码,需要由 HelloWorldTracer
方面进行检测。我的目标是找到 HelloWorld.main()
控制流中的所有方法调用。但我对与包 java.lang.* 中的任何类型相关的方法调用不感兴趣(例如:java.lang.StringBuilder
)。
package com.abc;
public class HelloWorld {
public static void main(String args[]) {
StringBuilder str = new StringBuilder();
str.toString();
Sample.testMethod();
}
}
package com.abc;
public class Sample {
public static void testMethod()
{
StringBuilder str = new StringBuilder();
str.toString();
}
}
public aspect HelloWorldTracer {
pointcut helloWorldTracker() :
execution(* com.sybase.HelloWorld.main(..)) && within(com.abc..*) && !within(HelloWorldTracer);
pointcut methodTracker():
cflow(helloWorldTracker())
&& !within(java.lang..*) && !within(HelloWorldTracer);
Object around(): methodTracker()
{
System.out.println("Inside advice..." + thisJoinPointStaticPart.getSignature().toString() );
Object o = proceed();
return o;
}
}
即使 !within(java.lang..*)
已在 methodTracker 中明确指定,也使用上面提到的切入点
切入点。我也尝试了 StringBuilder
类型()!within(java.lang.StringBuilder)
和 !execution(String java.langStringBuilder.toString(..))
,但没有成功。任何帮助限制来自 java.lang..* 的类型的建议都将不胜感激。
最佳答案
Nitzan Volman 的建议不是您想要的。
首先,在您的代码示例中,您可能想要更改
execution(* com.sybase.HelloWorld.main(..))
到
execution(* com.abc.HelloWorld.main(..))
修复该问题后,您会收到很多警告,因为您正尝试使用 around()< 来建议
由于编译器的限制,这是不可能的。initialization()
和 preinitialization()
切入点
然后当您将输出行更改为 just
System.out.println(thisJoinPointStaticPart);
您将看到您的代码中真正发生了什么:
execution(void com.abc.HelloWorld.main(String[]))
call(java.lang.StringBuilder())
call(String java.lang.StringBuilder.toString())
call(void com.abc.Sample.testMethod())
staticinitialization(com.abc.Sample.<clinit>)
execution(void com.abc.Sample.testMethod())
call(java.lang.StringBuilder())
call(String java.lang.StringBuilder.toString())
即您不仅仅是拦截方法调用(或者您的意思是捕获方法执行,这不一样吗?),而是所有(嗯,很多)种类的连接点。试试这个:
public aspect HelloWorldTracer {
pointcut belowHelloWorldMain() :
cflow(execution(* com.abc.HelloWorld.main(..)));
pointcut methodTracker():
belowHelloWorldMain() &&
call(* *(..)) &&
!call(* java.lang..*(..)) &&
!within(HelloWorldTracer);
Object around(): methodTracker() {
System.out.println(thisJoinPointStaticPart);
return proceed();
}
}
结果:
call(void com.abc.Sample.testMethod())
以防万一你只想拦截(而不是调用)你自己的(编织的)类的执行,它甚至更简单,因为这样你就不需要排除 Java 类:
public aspect HelloWorldTracer {
pointcut belowHelloWorldMain() :
cflow(execution(* com.abc.HelloWorld.main(..)));
pointcut methodTracker():
belowHelloWorldMain() &&
execution(* *(..));
Object around(): methodTracker() {
System.out.println(thisJoinPointStaticPart);
return proceed();
}
}
结果:
execution(void com.abc.HelloWorld.main(String[]))
execution(void com.abc.Sample.testMethod())
如您所见,现在甚至包括 main(..)
。
关于java - 在 aspectj 中使用 cflow() 时如何删除 java..* 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7808700/