如何使用 ASM 扫描字段和方法注释?
how to scan field&method annotations with ASM?
使用 ASM 5.0.4,我试图找到 class' 具有特定注释的字段和方法。我喜欢避免加载 class 而不必担心依赖性。
到目前为止,我无法弄清楚如何使用这种方法获得 field/method 注释:
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.
运行它对付一个简单的class
@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
但不是字段和方法的注释。
我怎样才能同时获得字段和方法注释?
您需要继承 FieldVisitor
and 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);
}
}
然后将它们连接到 visitField
和 visitMethod
中的 AnnotationScanner
。例如,将您的代码更改为
@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();
}
没有显示如何访问 @MyMethod
注释 (name="a method"
) 的 name
值。要同时读取 a method
值,您必须再添加两个 Visitors:
static class MethodAnnotationScanner extends MethodVisitor {
MethodAnnotationScanner() {
super(Opcodes.ASM8);
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
System.out.println("visitMethodAnnotation: type= " + desc);
return new MyAnnotationVisitor();
}
}
static class MethodAnnotationValueScanner extends AnnotationVisitor {
MethodAnnotationValueScanner() {
super(Opcodes.ASM8);
}
@Override
public void visit(String name, Object value) {
System.out.println("visitMethodAnnotationValue: " + name + " = " + value);
super.visit(name, value);
}
}
并通过将 MethodAnnotationScanner
更改为 visitMethod
:
来插入它们
@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();
}
您可以在此处查看完整的更新示例:how-to-read-a-java-class-method-annotation-value-with-asm
使用 ASM 5.0.4,我试图找到 class' 具有特定注释的字段和方法。我喜欢避免加载 class 而不必担心依赖性。 到目前为止,我无法弄清楚如何使用这种方法获得 field/method 注释:
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.
运行它对付一个简单的class
@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
但不是字段和方法的注释。
我怎样才能同时获得字段和方法注释?
您需要继承 FieldVisitor
and 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);
}
}
然后将它们连接到 visitField
和 visitMethod
中的 AnnotationScanner
。例如,将您的代码更改为
@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();
}
@MyMethod
注释 (name="a method"
) 的 name
值。要同时读取 a method
值,您必须再添加两个 Visitors:
static class MethodAnnotationScanner extends MethodVisitor {
MethodAnnotationScanner() {
super(Opcodes.ASM8);
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
System.out.println("visitMethodAnnotation: type= " + desc);
return new MyAnnotationVisitor();
}
}
static class MethodAnnotationValueScanner extends AnnotationVisitor {
MethodAnnotationValueScanner() {
super(Opcodes.ASM8);
}
@Override
public void visit(String name, Object value) {
System.out.println("visitMethodAnnotationValue: " + name + " = " + value);
super.visit(name, value);
}
}
并通过将 MethodAnnotationScanner
更改为 visitMethod
:
@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();
}
您可以在此处查看完整的更新示例:how-to-read-a-java-class-method-annotation-value-with-asm