gpt4 book ai didi

aop - 如何为一系列方法定义切点?

转载 作者:行者123 更新时间:2023-12-04 21:48:07 26 4
gpt4 key购买 nike

例如,如果我有 3 个类(class),

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 中获取参数并在方面方法中做一些事情一样。有人可以帮帮我吗。

最佳答案

让我稍微扩展一下您的示例代码,以便您了解我的解决方案能做什么和不能做什么:

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 是通过 C.doCB.doB间接调用的。我的解决方案也捕获了这种间接情况。如果这对您来说没问题或者它不会在您的代码库中发生,您可以使用我的解决方案。否则事情会变得有点复杂,您需要检查调用堆栈。如果您需要排除 #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。

关于aop - 如何为一系列方法定义切点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27374634/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com