ASM 基础

ASM is an all purpose Java bytecode manipulation and analysis framework.
Note that the scope of the ASM library is strictly
limited to reading, writing, transforming and analyzing classes.

 

核心的部件(类)
ClassReader :解析编译过的类,生成固定格式的字节数组。是访问者模式中的被访问者,通过访问来实现类的修改。 事件的生产者
ClassWriter :是 ClassVisitor 接口的实现,用来构建,生成字节类。 事件的消费者
ClassAdapter :也是 ClassVisitor 接口的实现,代理对于另外一个ClassVisitor的所有方法调用。所以可以起到过滤作用。 事件的过滤器     

 

工作过程 :查看ClassAdapter的源代码,可以发现里面有一个 ClassVisitor的字段(适配器模式),在生成ClassAdapter对象的时候初始化这个字段,这样的话这个对象即是 ClassVisitor,又带这一个ClassVisitor字段。那么在它所有的visitXXX方法中都可以有自己的实现,也可以调用这个字段的对 应方法,起到适配或代理的作用。当调用ClassReader的accept方法,并把最外层的ClassVisitor作为参数时 候,ClassReader就会作为被访问者,安排访问者的行踪,其实这是根据字节码的特点和偏移,ClassReader会按照特定的顺序,调用 ClassVisitor各个方法,用于实现对ClassReader解析过的类的修改,一般我们都希望构建出新的类,所以会把ClassWriter作 为最里层的ClassVisitor,ClassReader会判断ClassVisitor是不是ClassWriter,如果是则准备生成新的类。这 个顺序就是:
ClassReader-->ClassAdapter…> -->ClassWriter
中间的ClassAdapter实现了过滤的作用

 

MethodAdapter: MethodVisitor 接口的实现

 

对于具体的例子,由于内容比较多,这里只摘选核心代码:


            ClassReader cr = new ClassReader("asm.test.Account");//Account即使需要被修改的类
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            ClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw);//这个ClassAdapter会代理完成对Class类的修改,你可以做任意修 改,包含变量,方法,静态,类名,方法名...
            cr.accept(classAdapter, ClassReader.SKIP_DEBUG);
            byte[] data = cw.toByteArray();
            File file = new File(".//bin//asm//test//Account.class");//把生成的类写入文件
            FileOutputStream fout = new FileOutputStream(file);
            fout.write(data);
            fout.close();
          当然,你也可以不保存,直接加载使用:
            secureAccountClass = classLoader.defineClassFromClassFile(
               "asm.test.Account",data);

AddSecurityCheckMethodAdapter 类的源码:
public class AddSecurityCheckMethodAdapter extends MethodAdapter
{
    public AddSecurityCheckMethodAdapter(MethodVisitor mv)
    {
        super(mv);
        // TODO Auto-generated constructor stub
    }
    public void visitMethodInsn(
        final int opcode,
        final String owner,
        final String name,
        final String desc)
    {
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "asm/test/ZOtherOperation",
            "test", "()Ljava/lang/String;");//修改方法的内容
    }
}

 

优点: 资料还是比较多的,官方文档就比较丰富,内容很详细, 如果搜索的话,最好使用英文Google,百度中的内容太少,大都不是我们想要的
缺点:太底层,过多的需要了解虚拟机指令,class文件结构

你可能感兴趣的:(ASM 基础)