2015-12-24 2 views
2

Использование ASM 5.0.4, я пытаюсь найти классы и методы класса, имеющие определенную аннотацию. Мне нравится не загружать класс, чтобы не беспокоиться о зависимостях. До сих пор я не могу понять, как ухватить поля/метода аннотаций с этим подходом:Как сканировать поля и аннотации метода с помощью ASM?

class AnnotationScanner extends ClassVisitor{ 

    public AnnotationVisitor visitAnnotation(String desc, boolean visible){ 
     System.out.println("visitAnnotation: desc="+desc+" visible="+visible); 
     return super.visitAnnotation(desc,visible); 
    } 

    public void visitAttribute(Attribute attr){ 
     System.out.println("visitAttribute: attr="+attr); 
     super.visitAttribute(attr); 
    } 

    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value){ 
     System.out.println("visitField: access="+access+" name="+name+" desc="+desc+" signature="+signature+" value="+value); 
     return super.visitField(access,name,desc,signature,value); 
    } 

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

    public static void main(String[] args) throws Exception{ 
     for (String arg : args){ 
      FileInputStream in = new FileInputStream(new File(arg)); 
      ClassReader cr = new ClassReader(in); 
      cr.accept(new AnnotationScanner(Opcodes.ASM4),0); 
     } 
    } 
} 

Весь проект образец находится на GitHub.

Запуск его от простого класса

@MyClass(name="annotation scanner") 
public class Scannee{ 
    @MyField(name="a string field") public String aStringField; 
    @MyMethod(name="a method")  public void aMethod(){} 
} 

дает

visitAnnotation: desc=Lorg/springdot/sandbox/asm/MyClass; visible=true 
visitField: access=1 name=aStringField desc=Ljava/lang/String; signature=null value=null 
visitMethod: access=1 name=<init> desc=()V signature=null exceptions=null 
visitMethod: access=1 name=aMethod desc=()V signature=null exceptions=null 

но не пояснительные поля и метода.

Как я могу получить аннотации полей и методов?

ответ

3

Вам нужно будет создать подкласс FieldVisitor и MethodVisitor и переопределить метод visitAnnotation, похожий на ваш ClassVisitor подкласса. Например,

class FieldAnnotationScanner extends FieldVisitor { 
    public FieldAnnotationScanner() { 
     super(Opcodes.ASM5); 
    } 

    @Override 
    public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 
     System.out.println("visitAnnotation: desc="+desc+" visible="+visible); 
     return super.visitAnnotation(desc, visible); 
    } 
} 

class MethodAnnotationScanner extends MethodVisitor { 
    public MethodAnnotationScanner() { 
     super(Opcodes.ASM5); 
    } 

    @Override 
    public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 
     System.out.println("visitAnnotation: desc="+desc+" visible="+visible); 
     return super.visitAnnotation(desc, visible); 
    } 
} 

Затем подключите их к вашему AnnotationScanner в visitField и visitMethod. Например, изменить код

@Override 
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value){ 
    System.out.println("visitField: access="+access+" name="+name+" desc="+desc+" signature="+signature+" value="+value); 
    return new FieldAnnotationScanner(); 
} 

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

включивших фрагменты раствора в [образец кода] (https://github.com/m2spring/asm-eval/commit/b31666b208db33cfaa8b5d285e085799d7d3da2a). Оно работает. –