识别方法的不同执行(执行对象)?

时间:2012-08-03 17:17:32

标签: java aspectj

我有一些(静态)Java方法。

我有一个切入点可以触发任何这些方法的执行:

pointcut calculation() : execution(* myMethod_*(..));

现在我想分别测量每次执行的时间。 问题是执行可能随时触发,而其他执行仍在运行。 我考虑了两个建议,before()after(),它们可以识别呼叫者以管理不同呼叫者的定时器。

before() : calculation() {

}

after() : calculation() {

}

我该如何实现?

3 个答案:

答案 0 :(得分:2)

around()建议应该有效:

   Object around() : calculation() {
        long start = System.nanoTime();
        Object result = proceed();
        long end = System.nanoTime();
        logger.info(String.format("%s took %d ns", thisJoinPointStaticPart.getSignature(),
                (end - start)));
        return result;
    }

答案 1 :(得分:1)

我无法对Biju的答案发表评论,所以我正在创建一个新答案:

你问:

  

有一个问题:“建议[...]尚未应用[Xlint:adviceDidNotMatch]” - 似乎切入点与Java方法不再匹配

那么它应该如何匹配?执行静态方法后(您自己提到),没有this个对象,因此切入点应该是call()而不是execution()。以下是我为您演示的完整代码示例:

申请类:

package de.scrum_master.aspectj.sample;

import java.util.Random;

public class Dummy {
    static Random random = new Random();

    static void myMethod_one() throws InterruptedException {
        Thread.sleep(random.nextInt(1000));
    }

    static String myMethod_two(int dummy) throws InterruptedException {
        Thread.sleep(random.nextInt(1000));
        return "dummy";
    }

    static int myMethod_three(double foo, String... dummy) throws InterruptedException {
        Thread.sleep(random.nextInt(1000));
        return -1;
    }

    public static void main(String[] args) throws InterruptedException {
        // We have no "this" here (static method), so advice is not applied
        myMethod_two(5);
        myMethod_one();
        myMethod_three(7.7, "foo", "bar");

        // Now let's create an object, so we have "this"
        new Dummy().doStuff();
    }

    void doStuff() throws InterruptedException {
        // Here advice is applied because we have "this"
        myMethod_one();
        myMethod_two(5);
        myMethod_one();
        myMethod_three(7.7, "foo", "bar");
        myMethod_three(3.3, "zot", "baz");
        myMethod_two(11);
    }
}

时间方面:

package de.scrum_master.aspectj.sample;

aspect TimingAspect {
    pointcut calculation(Object thisObject) :
        call(* myMethod_*(..)) && this(thisObject);

    Object around(Object thisObject) : calculation(thisObject) {
        long start = System.nanoTime();
        Object result = proceed(thisObject);
        long end = System.nanoTime();
        System.out.println(String.format(
            "%s (this = %s) took %d ns",
            thisJoinPointStaticPart.getSignature(),
            thisObject,
            end - start
        ));
        return result;
    }
}

答案 2 :(得分:0)

最好的方法是使用具有开始时钟和结束时钟的对象包装每个方法。您可以使用:

System.nanoTime();

保存开始和结束时间。因此,您的前后调用可以设置开始和结束时间值。或者你可以将它们包装成一个运行命令,它设置start,运行方法,然后设置end。

通过将方法包装在一个对象中,您可以将时序控件抽象到该对象,并根据需要并行执行多个操作 - 每个都负责为自己的方法计时。