当前位置: 首页 > 知识库问答 >
问题:

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

冯亮
2023-03-14

我试图围绕使用自定义注释注释的方法定义一个切入点。注释有一个参数,我想在切入点定义中包含一个检查。

这是注释:

public @interface MyAnno {
  String[] types;
}

如何应用注释的示例:

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

现在我想有两个切入点定义,根据注释的内容选择这两种方法。

在注释本身上创建切入点相对容易:

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

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

这将匹配@MyAnno的每次出现。但是我如何定义两个切入点,一个将@MyAnno与包含"type1"类型匹配,另一个将@MyAnno与包含"type3"类型匹配

共有2个答案

太叔英卫
2023-03-14

您可以使用条件切入点来做到这一点,但这将涉及对注释属性的运行时测试。

本机方面语法:

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

基于注释的方面语法:

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

不要忘记导入java。util。两个示例的数组。

目前,从AeyJ版本1.8.13开始,您不能像使用非数组类型属性那样静态限制数组类型注释属性上的切入点表达式,因此此解决方案将涉及运行时测试

屈昊天
2023-03-14

目前,AeyJ支持对允许类型的注释值的子集进行注释值匹配。不幸的是,您使用的数组类型不受支持(也不支持类)。此功能记录在1.6.0 AeyJ README(https://eclipse.org/aspectj/doc/released/README-160.html)中。有一节是关于“注释值匹配”的。如上所述,对于基本情况,语法实际上非常直观:

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);
  }
}

因此,只需在注释中包含要匹配的值。不幸的是,数组情况更复杂,因此尚未实现。它需要更多的语法来允许您指定切入点是“在数组值中至少是这个”还是“在数组值中正好是这个并且只有这个”。据推测,这将重用<代码> 符号,可能是这样的:

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

如果没有语言支持,恐怕您必须以编程方式挖掘代码中的注释,以检查它是否符合您的约束。

 类似资料:
  • 假设我有一个注释,如下所示: 然后在Aspect中,我怎么可能想写两个切入点,一个用于所有用@DB操作(isRead操作=true)注释的方法,一个用于@DB操作(isRead操作=false)?

  • 到目前为止,我已经尝试了以下表达式,但没有成功: 有人能给我指出正确的解决办法吗?有可能吗?

  • 我有一个切入点,我试图用LTW。我有两个方法,我试图建议,每一个与不同的参数列表。但是,它们都有一个我想要的共同参数。 以下是我想建议的方法签名: 我本来希望参数与execution()方法相关联,但有时会出现“混淆”,给我的是IP而不是用户名。 是我不正确地使用了AspectJ,还是这是LTW中的一个bug?我运行的是AspectJ 1.6.13

  • 我试图在方法注释上创建一个Aeyj切入点,但我总是用不同的方法失败。我使用的是aspectj自动代理(我在Spring上下文中没有配置其他编织)。我的类如下所示: 所以我想知道为什么aspectj不会创建切入点。我设法使用执行(**(…)使其工作抛出一些exc)这对我来说很好,但我仍然想知道我做错了什么。 另外,由于是在接口中定义的,我指定了实现类的注释,有没有办法让它以这种方式工作?其他代理机制

  • 问题内容: 如果满足以下条件,则需要创建一个与方法匹配的切入点的方面: 它用MyAnnotationForMethod注释 它的参数之一(可以有多个)用@MyAnnotationForParam注释(但也可以具有其他注释)。 方面类看起来像这样 注释方法 随着日食->警告:在poincut: 使用http://download.eclipse.org/tools/ajdt/35/update中的最