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