AspectJ 在切入点上创建了大量方法

AspectJ creates plenty of methods on pointcut

我是 AOP 的新手(使用 AspectJ / ajc)并且已经在互联网上高低搜索/谷歌搜索以寻找我的难题的答案。希望这里有人可能拥有它。

正如我从文档中了解到的那样,AspectJ 应该注入代码。然而,根据我的经验,它似乎主要是在添加代码(并且只是交换方法调用)。

例如,如果我有方法:

private static int foo() {
    System.out.println("Hello world");
    return 1;
}

我为它定义了以下围绕建议(使用虚拟随机数来操纵 proceed() 与其他一些 return 值):

pointcut foo() : call(int com.mytest.aspects.HelloWorld.foo(..));
int around() : foo() {
    System.out.println("around()");
    if (System.currentTimeMillis() % 2 == 0)
        return proceed();
    return 0;
}

使用jd-gui反编译后得到如下信息:

  private static final int foo_aroundBody0()
  {
    return foo();
  }

  public static void main(String[] args)
  {
    foo_aroundBody1$advice(HelloAspect.aspectOf(), null);
  }

  private static final int foo_aroundBody1$advice(HelloAspect ajc$aspectInstance, AroundClosure ajc$aroundClosure)
  {
    System.out.println("around()");
    if (System.currentTimeMillis() % 2L == 0L)
    {
      AroundClosure localAroundClosure = ajc$aroundClosure;return foo_aroundBody0();
    }
    return 0;
  }

  private static int foo()
  {
     System.out.println("Hello world");
     return 1;
  }

如果是这样?我是不是做错了什么?

我尝试在我的 android 应用程序中使用 ajc,但多亏了一些 jar 和 SDK,我遇到了可怕的 "too many methods" 问题。

我大部分时间都在使用调用切入点,但是似乎这些额外的方法是为 each 调用添加的,即使是在同一个 class 中完成的和方法,从而显着增加我的代码大小和方法数量。

任何帮助理解这是否正确以及它是如何工作的将不胜感激!

你的理解基本正确。如果你想避免创建太多方法,请尽可能使用 execution() 切入点而不是 call(),因为这样每个被调用者只会创建一个合成方法,而不是每个调用者。 IE。如果从 25 个不同的地方调用一个方法,将只创建一个额外的方法而不是 25 个。

此外,您可以通过将方面的编织范围限制在真正需要的连接点来避免开销。我看到的大多数方面都融入了太多地方。此外,如果 before()after() 就足够了,请避免 around().