例如,如果我有3个班级,
class A {
public void doA() {
/* do something */
}
}
class B {
public void doB() {
A a = new A();
a.doA();
}
}
class MyClass {
public static void main(String args[]) {
B b = new B();
b.doB();
}
}
现在我想为流程doB()定义一个切点 - > doA(),就像doB()调用doA()从类A和类B中获取参数并在aspect方法中执行某些操作一样。有人可以帮助我。
答案 0 :(得分:2)
让我稍微扩展您的示例代码,以便让您了解我的解决方案做了什么以及它不能做什么:
class A {
public void doA() {}
}
class B {
public void doB() {
new A().doA();
new C().doC();
}
}
class C {
public void doC() {
new A().doA();
}
}
class MyClass {
public static void main(String args[]) {
new A().doA(); // should not be captured
new B().doB(); // should be captured
}
}
如您所见,现在有一个新类C
,我们现在有三个控制流程:
MyClass.main -> A.doA
MyClass.main -> B.doB -> A.doA
MyClass.main -> B.doB -> C.doC -> A.doA
你想要排除#1并捕获#2,但是#3呢?在这种情况下,a.doA
从B.doB
通过C.doC
被称为间接。我的解决方案也捕获了这种间接情况。如果这对您来说没问题,或者在您的代码库中没有发生,您可以使用我的解决方案。否则事情会变得复杂一些,你需要检查调用堆栈。告诉我你是否需要排除#2,我会扩展我的答案,但解决方案看起来不会像这个那么简单,我可以保证。
现在是方面:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class ControlFlowInterceptor {
@Before("execution(void A.doA()) && target(a) && cflow(execution(void B.doB()) && target(b))")
public void advice(JoinPoint thisJoinPoint, A a, B b) {
System.out.println(thisJoinPoint);
System.out.println(" " + a);
System.out.println(" " + b);
}
}
控制台输出如下所示:
execution(void A.doA())
A@7b19f779
B@65c66812
execution(void A.doA())
A@4df2868
B@65c66812
请注意,我们在两个输出中都有相同的B
对象ID,但由于C.doC
创建了一个新的A
对象,因此我们有两个不同的A
对象ID。