【问题标题】:How to read a Java class method annotation value with ASM如何使用 ASM 读取 Java 类方法注释值
【发布时间】:2020-05-14 21:31:29
【问题描述】:

如何在运行时使用 ASM 读取 Java 方法注释的值?
Annotation 只有一个 CLASS RetentionPolicy,因此无法使用 Reflections 来做到这一点。

|策略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 并通过反射来实现吗?
简而言之:不。我使用modelmapper 框架(简单、智能、对象映射)。在那里,我通过带注释的方法指定 Java 类之间的双向映射。我不想重用分层映射的这些信息来传播更改事件。但是提供的 mapstruct org.mapstruct.Mapping Annotation 有 CLASS RetentionPolicy。这就是为什么我需要从类文件中读取这些信息 - 并且需要 ASM

【问题讨论】:

    标签: java reflection annotations java-bytecode-asm modelmapper


    【解决方案1】:

    有许多示例显示了带有 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-26
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      相关资源
      最近更新 更多