目录 1.字节码增强技术 2.常见技术 3.ASM 3.1 测试 Main 3.2 测试 CustomerClassVisitor 3.3 测试 Test 1.字节码增强技术 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件
目录
- 1.字节码增强技术
- 2.常见技术
- 3.ASM
- 3.1 测试 Main
- 3.2 测试 CustomerClassVisitor
- 3.3 测试 Test
1.字节码增强技术
字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。
参考地址
2.常见技术
3.ASM
<dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>9.4</version> </dependency>
ASM Core API可以类比解析XML文件中的SAX方式,不需要把这个类的整个结构读取进来,就可以用流式的方法来处理字节码文件。好处是非常节约内存,但是编程难度较大。然而出于性能考虑,一般情况下编程都使用Core API。在Core API中有以下几个关键类:
3.1 测试 Main
package com.xu.test; /** * @author Administrator */ public class Main { public void print() { System.out.println("ASM"); } }
3.2 测试 CustomerClassVisitor
package com.xu.test; import org.apache.commons.lang3.StringUtils; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; /** * ASM 字节码增强技术 * * @author Administrator */ public class CustomerClassVisitor extends ClassVisitor implements Opcodes { public CustomerClassVisitor(ClassVisitor api) { super(ASM9, api); } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { cv.visit(version, access, name, signature, superName, interfaces); } @Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions); if (StringUtils.equals("print", name) && mv != null) { mv = new CustomerMethodVisitor(mv); } return mv; } class CustomerMethodVisitor extends MethodVisitor implements Opcodes { public CustomerMethodVisitor(MethodVisitor api) { super(ASM9, api); } @Override public void visitCode() { super.visitCode(); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("start"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); } @Override public void visitInsn(int opcode) { if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) { mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("end"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); } mv.visitInsn(opcode); } } }
3.3 测试 Test
package com.xu.test; import java.io.File; import java.io.FileOutputStream; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; /** * @author Administrator */ public class Test { public static void main(String[] args) throws Exception { ClassReader reader = new ClassReader("com/xu/test/Main"); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); // 处理 ClassVisitor visitor = new CustomerClassVisitor(writer); reader.accept(visitor, ClassReader.SKIP_DEBUG); // 输出 File file = new File("target\\classes\\com\\xu\\test\\Main.class"); FileOutputStream stream = new FileOutputStream(file); stream.write(writer.toByteArray()); stream.close(); // 测试 Class<?> cls = Class.forName("com.xu.test.Main"); Main main = (Main) cls.getDeclaredConstructor().newInstance(); main.print(); } }
到此这篇关于详解Java中的字节码增强技术的文章就介绍到这了,更多相关Java字节码增强内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!