在ASM的Core API中使用的是访问者模式来实现对类的操作,主要包含如下类:
一、ClassVisitor接口:
在这个接口中主要提供了和类结构同名的一些方法,这些方法可以对相应的类结构进行操作。如下:
public interface ClassVisitor { void visit(int version,int access,String name,String signature,String superName,String[] interfaces); void visitSource(String source, String debug); void visitOuterClass(String owner, String name, String desc); AnnotationVisitor visitAnnotation(String desc, boolean visible); void visitAttribute(Attribute attr); void visitInnerClass(String name,String outerName,String innerName,int access); FieldVisitor visitField(int access,String name,String desc,String signature,Object value); MethodVisitor visitMethod(int access,String name,String desc,String signature,String[] exceptions); void visitEnd(); }
这里定义的方法调用是有顺序的,在ClassVisitor中定义了调用的顺序和每个方法在可以出现的次数,如下:
visit [ visitSource ] [ visitOuterClass ] ( visitAnnotation | visitAttribute )* (visitInnerClass | visitField | visitMethod )* visitEnd。
二、ClassReader类:
这个类会提供你要转变的类的字节数组,它的accept方法,接受一个具体的ClassVisitor,并调用实现中具体的visit,
visitSource,visitOuterClass,visitAnnotation,visitAttribute,visitInnerClass,visitField,visitMethod和visitEnd方法。
三、ClassWriter类:
这个类是ClassVisitor的一个实现类,这个类中的toByteArray方法会将最终修改的字节码以byte数组形式返回,在这个类的构造时可以指定让系统自动为我们计算栈和本地变量的大小(COMPUTE_MAXS),也可以指定系统自动为我们计算栈帧的大小(COMPUTE_FRAMES)。
四、ClassAdapter类:
这个类也是ClassVisitor的一个实现类,这个类可以看成是一个事件过滤器,在这个类里,它对ClassVisitor的实现都是委派给一个具体的ClassVisitor实现类,即调用那个实现类实现的方法。
五、AnnotationVisitor接口:
这个接口中定义了和Annotation结构想对应的方法,这些方法可以操作Annotation中的定义,如下:
public interface AnnotationVisitor { void visit(String name, Object value); void visitEnum(String name, String desc, String value); AnnotationVisitor visitAnnotation(String name, String desc); AnnotationVisitor visitArray(String name); void visitEnd(); }
调用顺序如下:
(visit | visitEnum | visitAnnotation | visitArray)* visitEnd
六、FieldVisitor接口:
这个接口定义了和属性结构相对应的方法,这些方法可以操作属性,如下:
public interface FieldVisitor { AnnotationVisitor visitAnnotation(String desc, boolean visible); void visitAttribute(Attribute attr); void visitEnd(); }
调用顺序:
( visitAnnotation | visitAttribute )* visitEnd.
七、MethodVisitor接口:
这个接口定义了和方法结构相对应的方法,这些方法可以去操作源方法,具体的可以查看一下源码。
八、操作流程:
一般情况下,我们需要操作一个类时,首先是获得其二进制的字节码,即用ClassReader来读取一个类,然后需要一个能将二进制字节码写回的类,即用ClassWriter类,最后就是一个事件过滤器,即ClassAdapter。事件过滤器中的某些方法可以产生一个新的XXXVisitor对象,当我们需要修改对应的内容时只要实现自己的XXXVisitor并返回就可以了。
转载:http://victorzhzh.iteye.com/blog/875759