asm学习(4)--Tree API

asm文档阅读已快到尾声,最后一章已到Tree API的使用,Tree API就是针对Class,Method,Field等其它同级的属性进行了一个类包装,可以让我们用面向对像的形式来操作字节码,但也不要负于太高的期望,要操作字节码还真得弄懂了才能下手,Tree API带给我们的只是代码量的减少。Tree API是通过实现ClassVisitor接口而实现的,从另外一个角度来说就是给我们又封装了一层ClassVisitor,让我们开发便利点。

  同样,我们可以用它来实现AOP。

  ClassWriter cw = new ClassWriter(0);

  ClassNode classNode = new ClassNode();

  classNode.fields.add(new FieldNode(ACC_PUBLIC, "count", "I", null,

    new Integer(0)));

  ClassReader cr = new ClassReader("com.c2.asm.B");

  //注意classReader.accept的位置,必须为在填充了Node信息之前,如之后就得不到本来类中的信息。

  cr.accept(classNode, 0);

  List methods = classNode.methods;

  for (MethodNode mn : (List<MethodNode>) methods) {

   InsnList insns = mn.instructions;

   Iterator j = insns.iterator();

   while (j.hasNext()) {

    AbstractInsnNode in = (AbstractInsnNode) j.next();

    int op = in.getOpcode();

    //捕捉到结尾处

    if ((op >= IRETURN && op <= RETURN) || op == ATHROW) {

     InsnList il = new InsnList();

     il.add(new InsnNode(ICONST_3));

     il.add(new VarInsnNode(ISTORE,3));

     //在这里可以控制在什么地方插入新代码

     insns.insert(in.getPrevious(),il);

    }

   }

   InsnList il = new InsnList();

   il.add(new InsnNode(ICONST_4));

   il.add(new VarInsnNode(ISTORE,4));

   insns.insert(il);

   //同样,Stack和Locals瞎写的,猜得差不多吧

   mn.maxStack += 3;

   mn.maxLocals += 4;

  }

  //注意classNode.accept的位置,必须为在填充了Node信息之后

  classNode.accept(cw);

 

你可能感兴趣的:(tree)