gpt4 book ai didi

java - 在 aspectj 中使用 cflow() 时如何删除 java..* 调用?

转载 作者:行者123 更新时间:2023-12-04 20:13:34 25 4
gpt4 key购买 nike

我在以下示例代码中发现了我的问题。 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com