我正在尝试学习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())。检索该内容的最佳方法是什么?
不知道我是否理解正确,但是如果您需要访问有关上下文的信息,那么从您所感兴趣的连接点下的一段代码被调用的地方,那么您所需要的就是thisEnclosingJoinPointStaticPart
(本机AspectJ语法)。如果您正在使用AspectJ 5批注样式方面,只需将type添加一个参数到您的通知方法中JoinPoint.EnclosingStaticPart
。
请注意,这不适用于execution()
样式切入点,仅适用于call()
样式切入点,否则JoinPoint.EnclosingStaticPart
和JoinPoint.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] 删除。
我来说两句