java - AspectJ:跟踪新对象初始化

标签 java object initialization aspectj

我正在尝试理解 AspectJ。我想尝试计算项目中的所有对象初始化(这些对象是从我指定的类初始化的,而不是一些 Java 内部的类),但我真的不知道如何执行此操作。

假设我有名为 A 和 B 的类,其中 A 有子类 Aa 和 Ab,B 有子类 Ba 和 Bb,Bb 有子类 Bba。我希望我的方面能够跟踪以这些类为基础创建的对象的每个初始化,但我并不真正了解如何正确执行此操作(即使这应该有点简单)。到目前为止,我有类似的东西:

public aspect AspectCounter {
        private int objects = 0;

        pointcut countObjects() : initialization(A.new(..)) || initialization(B.new(..));

        pointcut printObjects() : call(* Test.printCounter(..));

        after() : countObjects() {
            objects++;
        }

        after() : printObjects() {
            System.out.println(objects);
        }
}

这至少打印了我创建的正确数量的 A 和 B(我没有使用 B*.new(..) ,因为按照我的理解,它会跟踪任何初始化Bba 三次,在这种情况下我不想要)。 现在的工作方式是,我有一个 Test 类,它可以进行测试,在完成测试后,我只是调用一个空的 printCounter 方法,它实际上不执行任何操作。它似乎有效并且确实给了我正确数量的对象,但我确信有更好的方法来做到这一点。我真的不喜欢有一个空的方法。

最佳答案

您无法通过 *.new(..) 上的初始化预初始化执行切入点来执行此操作因为它们的执行顺序。它们并不像您想象的那样嵌套,而是由于 JVM 的工作方式而按顺序执行。我已经详细解释过here包括示例代码和日志输出。因此,您只能选择使用call切入点。这是一个例子:

package de.scrum_master.app;

public class A {}
package de.scrum_master.app;

public class Aa extends A {}
package de.scrum_master.app;

public class Ab extends A {}
package de.scrum_master.app;

public class B {}
package de.scrum_master.app;

public class Ba extends B {}
package de.scrum_master.app;

public class Bb extends B {}
package de.scrum_master.app;

public class Bba extends Bb {}

驱动程序应用程序:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        new A();
        new Aa();
        new Ab();
        new B();
        new Ba();
        new Bb();
        new Bba();
    }
}

方面:

package de.scrum_master.aspect;

import de.scrum_master.app.A;
import de.scrum_master.app.B;

public aspect InstanceCreationCounter {
    private static int count;

    after() : call(A+.new(..)) || call(B+.new(..)) {
        System.out.printf("%4d %s%n", ++count, thisJoinPoint);
    }
}

控制台日志:

   1 call(de.scrum_master.app.A())
   2 call(de.scrum_master.app.Aa())
   3 call(de.scrum_master.app.Ab())
   4 call(de.scrum_master.app.B())
   5 call(de.scrum_master.app.Ba())
   6 call(de.scrum_master.app.Bb())
   7 call(de.scrum_master.app.Bba())

我想这就是你想要的。

警告:您需要控制所有调用代码并将方面编织到其中才能使其正常工作。

关于java - AspectJ:跟踪新对象初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34242498/

相关文章:

java - 如何在android中以YYYY-MM-DD HH:MI:Sec.Millisecond格式获取当前时间

object - 在哪里可以找到 .od 格式的模型?

javascript - 数组内部的对象——在一个范围内有效,但在另一个范围内无效?

python - Python 中的数组初始化

C#BeforeFieldInit乔恩·斯凯特(Jon Skeet)解释困惑

java - 如何从多行字符串中删除特定行

java - 如何在单个 Docker 容器中提供多模块 spring boot 应用程序?

java - 如何修复java中字符串分割的索引越界异常?

python - 在Python中使用导入类的对象作为另一个类的全局变量

c++ - 通过函数调用进行大括号或等号初始化