曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上) (4)

官网中有个demo,如下所示,可以修改class的版本:

public class ChangeVersionAdapter extends ClassVisitor { public ChangeVersionAdapter(ClassVisitor classVisitor) { super(ASM4, classVisitor); } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { cv.visit(V1_8, access, name, signature, superName, interfaces); } }

测试类:

public class TestChangeClassVersion { public static void main(String[] args) throws IOException { ClassReader classReader = new ClassReader("com.yn.classgenerate.CopyClass"); ClassWriter cw = new ClassWriter(0); ClassVisitor cv = new ChangeVersionAdapter(cw) { }; classReader.accept(cv, 0); byte[] b2 = cw.toByteArray(); File file = new File("F:\\gitee-ckl\\all-simple-demo-in-work\\asm-demo\\src\\main\\java\\com\\yn\\classgenerate\\CopyClass2.class"); FileOutputStream fos = new FileOutputStream(file); fos.write(b2); fos.close(); } }

官网还画了个图,贴心:

曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)

通过这样,classWriter中,版本号已经被改了,但它还被蒙在鼓里,可怜。

如果要删除字段、删除方法,怎么整

在ClassVisitor中,有几个特殊的方法:

曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)

主要就是这几个,你看他们的返回值,不太一样,是xxxVistor,和ClassVisitor有点像?那就对了。

我们看看fieldVisitor:

曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)

其结构和方法,都和ClassVisitor类似,也就是说,我们可以返回一个自定义的FieldVistor,然后,ASM框架,就会使用我们返回的这个FieldVisitor去visit我们的field的相关属性,回调fieldVisitor中的相关方法。

那,怎么删除呢?返回null。

这么简单吗,是的。

package com.yn.classgenerate; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import static org.objectweb.asm.Opcodes.ASM6; // 该demo来自官网文档 public class RemoveMethodAdapter extends ClassVisitor { private String mName; private String mDesc; public RemoveMethodAdapter( ClassVisitor cv, String mName, String mDesc) { super(ASM6, cv); this.mName = mName; this.mDesc = mDesc; } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals(mName) && desc.equals(mDesc)) { // 这样就可以了。 // do not delegate to next visitor -> this removes the method return null; } return cv.visitMethod(access, name, desc, signature, exceptions); } } 总结

asm的基本操作大概如此,这些比较粗浅,下一讲我们会实现一个有用一点的东西,会结合java的instrument机制来讲。

大家要跟着我的demo一起来实践,https://gitee.com/ckl111/all-simple-demo-in-work/tree/master/asm-demo

这样才能学的劳。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfxsf.html