在AspectJ中使用cflow()时如何删除java .. *调用? [英] How to remove java..* calls while using cflow() in aspectj?

查看:120
本文介绍了在AspectJ中使用cflow()时如何删除java .. *调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面的示例代码中捕获了我的问题. HelloWorld类是我的源,需要通过HelloWorldTracer方面进行检测.我的目标是找到HelloWorld.main()的控制流中的所有方法调用.但是我对与包java.lang.*(例如:java.lang.StringBuilder)中的任何类型相关的方法调用都不感兴趣.

I have captured my problem in the following sample code. HelloWorld class is my source which needs to be instrumented by HelloWorldTracer aspect. My objective is to find all the method calls which are in the control flow of HelloWorld.main(). But I'm not interested in the method calls related to any types in the package java.lang.* (eg: 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;
    }

}

即使在methodTracker()切入点中明确指定了!within(java.lang..*),也建议使用上述类型的StringBuilder切入点.我也尝试了!within(java.lang.StringBuilder)!execution(String java.langStringBuilder.toString(..)),但是徒劳.在限制java.lang .. *中的类型方面的任何帮助都将不胜感激.

Using the poincuts mentioned above the type StringBuilder is also getting advised even though !within(java.lang..*) has been explicitly specified in methodTracker() pointcut. I also tried !within(java.lang.StringBuilder) and !execution(String java.langStringBuilder.toString(..)) as well, but in vain. Any help in restricting the types from java.lang..* from getting advised will be appreciated.

推荐答案

尼桑·沃尔曼(Nitzan Volman)的建议不是您想要的.

Nitzan Volman's suggestion is not what you want.

首先,您可能想在代码示例中进行更改

First of all, in your code sample probably you want to change

execution(* com.sybase.HelloWorld.main(..))

execution(* com.abc.HelloWorld.main(..))

已修复此问题,将收到很多警告,因为您尝试使用around()建议initialization()preinitialization()切入点,由于编译器的限制,这是不可能的.

Having fixed that, you will get a lot of warnings because you are trying to advise initialization() and preinitialization() pointcuts with around() which is impossible due to compiler limitations.

然后,当您将输出行更改为公正

Then when you change your output line to just

System.out.println(thisJoinPointStaticPart);

您将看到代码中实际发生的情况:

You will see what really happens in your code:

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

即您不仅在拦截方法调用(或者是要捕获方法执行,这是不一样的?),而且还包括所有(很多)连接点.试试这个:

I.e. you are not just intercepting method calls (or did you mean to catch method executions, which is not the same?), but all (well, many) sorts of joinpoints. Try this:

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类:

Just in case you only wanted to intercept executions of (instead of calls to) your own (woven) classes anyway, it is even simpler, because then you do not need to exclude the Java classes:

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

As you can see, now even main(..) is included.

这篇关于在AspectJ中使用cflow()时如何删除java .. *调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆