我有两个不同的方面类来计算执行测试程序的非静态方法调用的数量.第一个方面计算"呼叫"连接点的方法:
pointcut methodCalls() : call (!static * test..*(..));
before(): methodCalls() {
counter.methodCallCounter();
}
Run Code Online (Sandbox Code Playgroud)
而第二个方面计算"执行"连接点的方法:
pointcut methodCalls() : execution (!static * test..*(..));
before(): methodCalls() {
counter.methodCallCounter();
}
Run Code Online (Sandbox Code Playgroud)
methodCallCounter()是计数器类中的静态方法.
小测试程序的方法调用次数是相同的.但是当我用更大的程序更改测试程序时,第二个方面类(带执行切入点)中的方法调用数量大于带有调用切入点的方面类中的方法调用数.这是合理的,因为调用连接点不会选择使用super进行的调用,因此不会对它们进行计数.
但是,我遇到了一种情况,对于程序的特定执行,具有"调用切入点"的方面类中的非静态方法调用的数量高于具有"执行切入点"的方面类中的方法调用的数量.我找不到任何解释为什么会发生这种情况.任何关于第二种情况的原因的想法都值得赞赏.
我需要使用@X注释的类中的方法或使用@X注释的方法的切入点.我还需要注释对象.如果类和方法都被注释,我更喜欢将方法注释作为参数.
我尝试了以下操作,这会产生"不一致的绑定"警告.(为什么不将它们设置为null?)
@Around("@annotation(methodLevelX) || @within(classLevelX)")
public Object advise(ProceedingJoinPoint pjp, X methodLevelX, X classLevelX)
Run Code Online (Sandbox Code Playgroud)
以下内容创建了"跨越'||'的参数x的模糊绑定 在切入点"警告.(在我看来,这不一定有意义:为什么不绑定第一个短路评估?)
@Around("@annotation(x) || @within(x)")
public Object advise(ProceedingJoinPoint pjp, X x)
Run Code Online (Sandbox Code Playgroud)
如果存在类和方法注释,则将先前的尝试拆分为两个自然会导致两个方法调用.
我知道我可以通过这样的切入点获得带有反射和我想要的注释的方法和类:
@Around("@annotation(com.package.X) || @within(com.package.X)")
Run Code Online (Sandbox Code Playgroud)
但我不愿意.
有没有"一个切入点,一个方法,一个注释参数",我的要求的解决方案不需要反思?
在 Java 中的 AOP (AspectJ) 中,当我们谈论方法切入点时,我们可以将它们区分为两个不同的集合:method call pointcuts和method execution pointcuts.
基于 SO 上的这些资源:
以及一些 AspectJ 背景,我们可以看出,基本上两者之间的差异可以表示如下:
鉴于这些类:
class CallerObject {
//...
public void someMethod() {
CompiletimeTypeObject target = new RuntimeTypeObject();
target.someMethodOfTarget();
}
//...
}
class RuntimeTypeObject extends CompileTypeObject {
@Override
public void someMethodOfTarget() {
super.someMethodOfTarget();
//...some other stuff
}
}
class CompiletimeTypeObject {
public void someMethodOfTarget() {
//...some stuff
}
}
Run Code Online (Sandbox Code Playgroud)