简体   繁体   English

aspectj切入点匹配特定的注释参数值

[英]aspectj pointcut matching a specific annotation parameter value

I'm trying to define a pointcut around a method annotated with a custom annotation. 我正在尝试围绕使用自定义注释注释的方法定义切入点。 The annotation has one parameter that I would like to include a check in the pointcut definition. 注释有一个参数,我想在切入点定义中包含一个检查。

This is the annotation: 这是注释:

public @interface MyAnno {
  String[] types;
}

An example of how the annotation could be applied: 如何应用注释的示例:

public class MyClass {
  @MyAnno(types={"type1", "type2"})
  public void doSomething() {
    // ...
  }
  @MyAnno(types={"type3"})
  public void doSomethingElse() {
    // ...
  }
}

Now I would like to have two pointcut definitions which select those two methods, based on the contents of the annotation. 现在我想有两个切入点定义,根据注释的内容选择这两种方法。

Creating a pointcut on the annotation itself is relatively easy: 在注释本身上创建切入点相对容易:

@Pointcut("@annotation(myAnno)")
public void pointcutAnno(MyAnno myAnno) {
}

@Pointcut("execution(* *(..)) && pointcutAnno(myAnno)")
public void pointcut(MyAnno myAnno) {
}

This will match every occurrence of the of @MyAnno. 这将匹配@MyAnno的每次出现。 But how can I define two pointcuts, one matching @MyAnno with types containing "type1" and the other matching @MyAnno with types containing "type3" 但是如何定义两个切入点,一个匹配@MyAnnotypes包含"type1" ,另一个匹配@MyAnnotypes包含"type3"

Currently AspectJ supports annotation value matching for a subset of the allowed kinds of annotation value. 目前,AspectJ支持对允许种类的注释值的子集进行注释值匹配。 Unfortunately the array type you are using is not supported (class isn't supported either). 不幸的是,不支持您使用的数组类型(也不支持类)。 This feature is documented in the 1.6.0 AspectJ README ( https://eclipse.org/aspectj/doc/released/README-160.html ). 1.6.0 AspectJ README( https://eclipse.org/aspectj/doc/released/README-160.html )中记录了此功能。 There is a section on 'Annotation value matching'. 有一个关于'注释值匹配'的部分。 As described there the syntax is actually quite intuitive for the basic cases: 如上所述,语法实际上对于基本情况非​​常直观:

enum TraceLevel { NONE, LEVEL1, LEVEL2, LEVEL3 }

@interface Trace {
  TraceLevel value() default TraceLevel.LEVEL1;
}

aspect X {
  // Advise all methods marked @Trace except those with a tracelevel of none
  before(): execution(@Trace !@Trace(TraceLevel.NONE) * *(..)) {
    System.err.println("tracing "+thisJoinPoint);
  }
}

So just include the value you want to match on in the annotation. 因此,只需在注释中包含要匹配的值即可。 Unfortunately the array case is more complicated and so not implemented yet. 不幸的是阵列情况更复杂,因此尚未实现。 It needs a little more syntax to allow you to specify whether your pointcut means 'at least this in the array value' or 'exactly this and only this in the array value'. 它需要更多的语法来允许您指定您的切入点是否意味着“至少在数组值中”或“确切地说这是在数组值中只有这个”。 Presumably that would reuse .. notation, something like this maybe: 据推测,这将重用..符号,这样的事情可能:

execution(@MyAnno(types={"type1"}) * *(..)) { // exactly and only 'type1'
execution(@MyAnno(types={"type1",..}) * *(..)) { // at least 'type1'

Without the language support I'm afraid you do have to programmatically dig through the annotation in your code to check if it matches your constraint. 如果没有语言支持,我恐怕你必须以编程方式挖掘代码中的注释,以检查它是否与你的约束相匹配。

You can do it with conditional pointcuts but those will involve a runtime test on the annotation attribute. 您可以使用条件切入点来完成它,但这些将涉及对注释属性的运行时测试。

Native aspect syntax: 原始方面语法:

pointcut p(MyAnno myAnno): execution(* *(..)) 
    && @annotation(myAnno) 
    && if(Arrays.stream(myAnno.types()).anyMatch("type1"::equals));

Annotation based aspect syntax: 基于注释的方面语法:

@Pointcut("execution(* *(..)) && @annotation(myAnno) && if()")
public boolean pointcut(MyAnno myAnno) {
    return !Arrays.stream(myAnno.types()).anyMatch("type1"::equals);
}

Don't forget to import java.util.Arrays for both examples. 不要忘记为这两个示例导入java.util.Arrays

Currently, as of AspectJ version 1.8.13, you cannot statically restrict pointcut expressions on array typed annotation attributes as you would be able with non-array typed attributes, so this solution will involve a runtime test instead. 目前,从AspectJ版本1.8.13开始,您无法静态地限制数组类型注释属性上的切入点表达式,就像使用非数组类型属性一样,因此此解决方案将涉及运行时测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM