繁体   English   中英

如何使用 ASM 读取 Java class 方法注释值

[英]How to read a Java class method annotation value with ASM

如何在运行时使用ASM读取 Java 方法注释的值?
注释只有一个CLASS RetentionPolicy ,所以用反射是不可能的。

| 策略CLASS :注释将由编译器记录在 class 文件中,但不需要在运行时由 VM 保留

示例
我想在运行时从artist字段中提取值Carly Rae Jepsen

public class SampleClass {

    @MyAnnotation(artist = "Carly Rae Jepsen")
    public void callMeMaybe(){}
}
@Documented
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface MyAnnotation {

    String artist() default "";
}

但为什么?
您不能将RetentionPolicy更改为RUNTIME并使用反射来完成吗?
简而言之:不。我使用模型映射器框架(简单、智能、 Object映射)。 在那里,我通过注释方法指定 Java 类之间的双向映射。 我不想重用分层映射的这些信息来传播更改事件。 但是提供的mapstruct org.mapstruct.Mapping Annotation 有CLASS RetentionPolicy 这就是为什么我需要从 class 文件中读取这些信息 - 并且需要ASM

有许多示例显示了带有 asm 和阅读注释的设置。 但是他们没有展示它,用于方法注释以及如何读取注释值。

最小的例子如何做到这一点:

import org.objectweb.asm.*;

public class AnnotationScanner extends ClassVisitor {
    public static void main(String[] args) throws Exception {
        ClassReader cr = new ClassReader(SampleClass.class.getCanonicalName());
        cr.accept(new AnnotationScanner(), 0);
    }

    public AnnotationScanner() {
        super(Opcodes.ASM8);
    }

    static class MyAnnotationVisitor extends AnnotationVisitor {
        MyAnnotationVisitor() {
            super(Opcodes.ASM8);
        }
        @Override
        public void visit(String name, Object value) {
            System.out.println("annotation: " + name + " = " + value);
            super.visit(name, value);
        }
    }

    static class MyMethodVisitor extends MethodVisitor {
        MyMethodVisitor() {
            super(Opcodes.ASM8);
        }
        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            System.out.println("annotation type: " + desc);
            return new MyAnnotationVisitor();
        }
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
                                     String signature, String[] exceptions) {
        System.out.println("method: name = " + name);
        return new MyMethodVisitor();
    }
}

Maven 依赖

<dependency>
  <groupId>org.ow2.asm</groupId>
  <artifactId>asm</artifactId>
  <version>8.0.1</version>
</dependency>

它将打印:

method: name = callMeMaybe
annotation type: Lorg/springdot/sandbox/asm/simple/asm/MyAnnotation;
annotation: artist = Carly Rae Jepsen

暂无
暂无

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

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