我是AOP的新手(使用AspectJ / ajc)并搜索/搜索互联网的高低搜索我的拼图的答案。希望有人可以拥有它。
正如我在文档中理解的那样,AspectJ假设注入代码。然而,根据我的经验,它似乎主要是添加代码(并简单地交换方法调用)。
例如,如果我有方法:
private static int foo() {
System.out.println("Hello world");
return 1;
}
我定义了以下围绕它的建议(使用虚拟随机来操纵proceed()与其他一些返回值):
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,我得到了可怕的"太多的方法"问题
我大部分时间都在使用调用切入点,但似乎为每次调用添加了这些额外的方法,即使在同一个类和方法中完成,从而增加了我的代码大小和方法计数显着。
任何帮助,了解这是否正确以及如何运作将非常感谢!
答案 0 :(得分:2)
您的理解是正确的。如果要避免创建太多方法,请尽可能使用execution()
切入点而不是call()
,因为每个被调用者只会创建一个合成方法,而不是每个调用者。即如果从25个不同的地方调用一个方法,则只会创建一个额外的方法而不是25个。
此外,您可以通过将方面的编织范围限制为真正需要的连接点来避免开销。我看到的大多数方面编织得太多了。此外,如果before()
或after()
足够,请避免around()
。