@yulongsun
2018-04-19T15:58:52.000000Z
字数 2202
阅读 847
Spring源码走读
简介
asm是一个开源的字节码操作库。可以用二进制的方式创建或者修改类。
注:asm的创建class文件过程中,操作的是底层JVM的汇编指令。
测试案例
public class AsmTest {
@Test
public void testCreateClass() {
ClassWriter classWriter = new ClassWriter(0);
// 创建类
classWriter.visit(Opcodes.V1_8, //java版本
Opcodes.ACC_PUBLIC, // 类的访问权限
"AsmClazz", //类名
null,
"java/lang/Object",
null);
// 创建构造函数
MethodVisitor constructMethod = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
constructMethod.visitCode();
constructMethod.visitVarInsn(Opcodes.ALOAD, 0);
constructMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "<init>", "()V");
constructMethod.visitInsn(Opcodes.RETURN);
constructMethod.visitMaxs(1, 1);
constructMethod.visitEnd();
// 创建code
MethodVisitor visitMethod = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "say", "()V", null, null);
visitMethod.visitCode();
visitMethod.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream");
visitMethod.visitLdcInsn("I'm a asm class .");
visitMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
visitMethod.visitInsn(Opcodes.RETURN);
visitMethod.visitMaxs(2, 2);
visitMethod.visitEnd();
//
//输出到文件
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File("AsmCode.class"));
fileOutputStream.write(classWriter.toByteArray());
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
生成代码如下:
public class AsmClazz {
public AsmClazz() {
}
public void say() {
System.out.println("I'm a asm class .");
}
}
简介
javassists是一个开源的分析、编辑、创建字节码的类库。
是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。
优点是:简单、快速、不需要了解JVM指令就能动态的改变类。
测试案例
public class JavassistTest {
@Test
public void testCreateClass() throws CannotCompileException, NotFoundException, IOException {
ClassPool classPool = ClassPool.getDefault();
//定义类
CtClass ctClass = classPool.makeClass("JavassistClazz");
//定义code方法
CtMethod ctMethod = CtNewMethod.make("public void say(){}", ctClass);
//插入方法代码
ctMethod.insertBefore("System.out.println(\"I'm Javassist Class\");");
ctClass.addMethod(ctMethod);
//
ctClass.writeFile();
System.out.println("代码生成结束");
}
}
生成代码如下:
public class JavassistClazz {
public void say() {
System.out.println("I'm Javassist Class");
}
public JavassistClazz() {
}
}
动态代理