AspectJ控制流/多个连接点

用户名

我正在尝试学习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

因此,对于这些类,我想提出一个方面,该方面基本上可以@Example在a内找到任何类型的被调用对象,@Test这样我就可以访问两个(或多个)连接点,在这里我可以从AspectJJoinPoint对象中获取方法/类签名

我尝试过这样的事情:

@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())。检索该内容的最佳方法是什么?

南多·埃尔德·布莱克(NándorElődBlack)

不知道我是否理解正确,但是如果您需要访问有关上下文的信息,那么从您所感兴趣的连接点下的一段代码被调用的地方,那么您所需要的就是thisEnclosingJoinPointStaticPart(本机AspectJ语法)。如果您正在使用AspectJ 5批注样式方面,只需将type添加一个参数到您的通知方法中JoinPoint.EnclosingStaticPart

请注意,这不适用于execution()样式切入点,仅适用于call()样式切入点,否则JoinPoint.EnclosingStaticPartJoinPoint.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() was invoked from void q35991663.com.example.ExampleTest.shouldTestSomething()

我也改写了你的examplePointCut切入点表达式@annotation(com.example.Example)将意味着

主题具有类型注释的任何连接点 com.example.Example

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章