gpt4 book ai didi

java - AspectJ 控制流/多个连接点

转载 作者:行者123 更新时间:2023-11-30 03:00:55 24 4
gpt4 key购买 nike

我正在尝试学习 AspectJ 并弄清楚如何检索流程中某些点的特定连接点。我的例子是这样的:

我想运行一个用 JUnit 的 @Test 注释的单元测试,然后在该测试中调用的任何方法可能位于用另一个注释注释的另一个类中,比方说 @Example,然后我基本上可以在这些特定点访问整个流程,因此我能够获取用 @Test 注释的测试的类名/方法名,然后还获取该测试的方法信息方法注释为@Example。我提供了一些示例代码以供澄清:

测试类:

public class ExampleTest {
@Test
public void shouldTestSomething() {
ExampleClass exampleClazz = new ExampleClass();
exampleClazz.something();
// ...
}

POJO:

public class ExampleClass {
@Example
public void something() {
// do something
end
end

因此,通过这些类,我想创建一个方面,基本上可以找到在 @Test 中调用的任何类型的 @Example ,这样我就可以访问我可以在两个(或多个)连接点中从 AspectJ JoinPoint 对象获取方法/类签名。

我尝试过这样的事情:

@Aspect
public class ExampleAspect {
@Pointcut("execution(@org.junit.Test * *(..))
&& !within(ExampleAspect)")
public void testPointCut() {}

@Pointcut("@annotation(com.example.Example)")
public void examplePointCut() {}

@After("cflow(testPointCut) && examplePointCut()")
public void doSomething(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature());
}
}

但是输出看起来像这样:

void ExampleTest.ExampleClass.something()

主要问题是签名中缺少测试方法的名称(shouldTestSomething())。检索它的最佳方法是什么?

最佳答案

不确定我是否理解正确,但如果您需要访问有关调用您感兴趣的连接点下的一段代码的上下文的信息,那么您需要的是 thisEnendingJoinPointStaticPart (使用 native AspectJ 语法)。如果您使用 AspectJ 5 注释样式方面,只需向您的通知方法添加一个类型为 JoinPoint.EnendingStaticPart 的参数。

请注意,这不适用于 execution() 样式切入点,仅适用于 call() 样式切入点,否则 JoinPoint.EnendingStaticPartJoinPoint.StaticPart 将是相同的。

这意味着您需要按以下方式重写您的方面:

@Aspect
public class ExampleAspect {

@Pointcut("execution(@org.junit.Test * *(..)) && !within(ExampleAspect)")
public void testPointCut() {
}

@Pointcut("call(@com.example.Example * *(..))")
public void examplePointCut() {
}

@After("cflow(testPointCut()) && examplePointCut()")
public void doSomething(JoinPoint joinPoint, EnclosingStaticPart enclosingStaticPart) {
System.out.println(joinPoint.getSignature() + " was invoked from "
+ enclosingStaticPart.getSignature());
}

}

测试代码的输出将是:

void q35991663.com.example.ExampleClass.something() 是从 void q35991663.com.example.ExampleTest.shouldTestSomething() 调用的

我还重写了您的examplePointCut。切入点表达式 @annotation(com.example.Example) 的意思是

any join point where the subject has an annotation of type com.example.Example

其中将包括 execution()call() 类型连接点。在这种情况下,我们只需要 call() 连接点,因此如果您不打算将注释的值绑定(bind)到,则甚至不需要 @annotation()建议上下文。

关于java - AspectJ 控制流/多个连接点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35991663/

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