【问题标题】:AspectJ : Find the source method code/name of a found JoinPointAspectJ : 查找找到的 JoinPoint 的源方法代码/名称
【发布时间】:2020-02-12 14:37:00
【问题描述】:

我想检索调用特定方法的调用方法。
示例:
我考虑的方法:

public void methodA(int a, int b){...}

在测试方法和程序本身中调用

@Test
public void testMethodA(
... some code...
objectClassA.methodA(x,y);
)}

Class B {
...
 public void methodB(){
    objectClassA.methodA(x,y);
   }
}

我想以某种方式获得的是 testMethodAmethodB 的内部或至少签名

为此,我认为 AspectJ 可以帮助我,所以我对此进行了研究并最终写了这个 poincut
pointcut pcmethodA(): execution(* A.methodA(..) );

我的建议看起来像这样

before(): pcmethodA() {
        System.out.println("[AspectJ] Entering " + thisJoinPoint);
        System.out.println("[AspectJ] Signature " + thisJoinPoint.getSignature());
        System.out.println("[AspectJ] SourceLocation "+ thisJoinPoint.getSourceLocation());

但这会返回

[AspectJ] Entering execution(void com.example.somePackage.A.methodA(int, int)
[AspectJ] Signature com.example.somePackage.A.methodA(int, int)
[AspectJ] SourceLocation A.java:25   /** Line number of the methodA in the file **/

这是我第一次使用 AspectJ ,是否有任何对象或方法来检索我找到的连接点的调用方法? testMethodAmethodB

谢谢

【问题讨论】:

  • 您没有合适的工具来完成这项工作。这不是 AspectJ 的用途——它不会产生完整的调用堆栈。您必须获取并检查线程堆栈跟踪。
  • 确实使用堆栈跟踪可能是更好的解决方案。谢谢

标签: java aop aspectj aspectj-maven-plugin


【解决方案1】:

让我先用几个示例类 + 驱动程序应用程序重新创建您的情况:

package de.scrum_master.app;

public class Foo {
  public void methodA(int a, int b) {
    System.out.println("methodA: " + a + ", " + b);
  }
}
package de.scrum_master.app;

public class DummyTest {
  public void testSomething() {
    new Foo().methodA(33, 44);
  }
}
package de.scrum_master.app;

public class Application {
  public void doSomething() {
    new Foo().methodA(11, 22);
  }

  public static void main(String[] args) {
    new Application().doSomething();
    new DummyTest().testSomething();
  }
}

现在在你的方面尝试call()thisEnclosingJoinPointStaticPart 的组合:

package de.scrum_master.aspect;

import de.scrum_master.app.Foo;

public aspect MyAspect {
  pointcut pcmethodA() : call(* Foo.methodA(..));

  before() : pcmethodA() {
    System.out.println("[AspectJ] Executing: " + thisJoinPoint);
    System.out.println("[AspectJ] Called by: " + thisEnclosingJoinPointStaticPart);
  }
}

运行Application时的控制台日志:

[AspectJ] Executing: call(void de.scrum_master.app.Foo.methodA(int, int))
[AspectJ] Called by: execution(void de.scrum_master.app.Application.doSomething())
methodA: 11, 22
[AspectJ] Executing: call(void de.scrum_master.app.Foo.methodA(int, int))
[AspectJ] Called by: execution(void de.scrum_master.app.DummyTest.testSomething())
methodA: 33, 44

看到了吗?如果您只想确定调用者和被调用者,则无需处理堆栈跟踪。

【讨论】:

  • 看起来确实很棒,但在我的情况下,它为 thisJoinPoint 和 thisEnclosureJoinPointStaticPart (?) 提供了相同的结果。我的上下文是我只使用“mvn test”命令运行应用程序。但是 Stacktrace 操作方法是正确的,使用相同的程序。
  • 如果它给出相同的结果,您可能仍然使用execution() 而不是我建议的call()。下次请仔细阅读我的回答。
  • 确实是我的错。我不知何故被困在“执行”类型的切入点上……谢谢
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多