java AspectJ - meta/嵌套注解参数绑定

cld4siwp  于 2023-03-28  发布在  Java
关注(0)|答案(1)|浏览(149)

我已经定义了一个 meta注解和一些用元注解的具体注解。我目前正在尝试实现一个方面,它将基于元注解编织用这些具体注解注解的方法。我能够使用这个切入点来实现通知调用。

"execution(@(@my.meta.Annotation *) * *(..))"

然而,我想使用参数绑定,因为 meta注解定义了一个我感兴趣的字段。不幸的是,我无法找到一个正确的表达式来实现这一点。
在使用嵌套的注解切入点时,是否可以使用参数绑定,或者是否需要从JoinPoint获取注解?

pqwbnv8z

pqwbnv8z1#

通过@annotation()进行注解绑定,@within()需要一个精确的类,但你想要一个通用的解决方案。因此,你需要通过反射从方法中获取注解,也就是说,你需要采取以下路线:
joinpoint → signature → method → annotation → metaannotation

package de.scrum_master.stackoverflow.q75834894.app;

import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;

@Retention(RUNTIME)
public @interface Meta {
  String id();
}
package de.scrum_master.stackoverflow.q75834894.app;

import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;

@Retention(RUNTIME)
@Meta(id = "indirect")
public @interface Marker {}
package de.scrum_master.stackoverflow.q75834894.app;

public class Application {
  public static void main(String[] args) {
    Application application = new Application();
    application.notAnnotated();
    application.metaAnnotated();
    application.markerAnnotated();
  }

  public void notAnnotated() {}
  @Meta(id = "direct") public void metaAnnotated() {}
  @Marker public void markerAnnotated() {}
}
package de.scrum_master.stackoverflow.q75834894.aspect;

import java.lang.annotation.Annotation;
import org.aspectj.lang.reflect.MethodSignature;
import de.scrum_master.stackoverflow.q75834894.app.Meta;

public aspect MyAspect {
  before(Meta meta) : @annotation(meta) && execution(* *(..)) {
    System.out.println(thisJoinPoint);
    System.out.println("  " + meta.id());
  }

  before() : execution(@(@de.scrum_master.stackoverflow.q75834894.app.Meta *) * *(..)) {
    System.out.println(thisJoinPoint);
    for (Annotation annotation : ((MethodSignature) thisJoinPoint.getSignature()).getMethod().getAnnotations()) {
      Meta meta = annotation.annotationType().getAnnotation(Meta.class);
      if (meta != null)
        System.out.println("  " + meta.id());
    }
  }
}

我猜您知道如何将原生语法方面转换为基于注解的方面语法,如果您喜欢的话。
控制台日志:

execution(void de.scrum_master.stackoverflow.q75834894.app.Application.metaAnnotated())
  direct
execution(void de.scrum_master.stackoverflow.q75834894.app.Application.markerAnnotated())
  indirect

相关问题