一、什么是ASM
ASM是一个JAVA字节码分析、创建和修改的开源应用框架。在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵活的操作字节码的方式。目前ASM已被广泛的开源应用架构所使用,例如:Spring、Hibernate等。
二、ASM能干什么
分析一个类、从字节码角度创建一个类、修改一个已经被编译过的类文件
三、ASM初探例子
这里我们使用ASM的CoreAPI(ASM提供了两组API:Core和Tree,Core是基于访问者模式来操作类的,而Tree是基于树节点来操作类的)创建一个Person类,目标类如下:
package test;
public class Person {
private String name;
public Person(){
this.name = "Sum";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这个类在构造方法中初始化了属性name,并提供了两个public方法来修改和访问name属性。
接下来就要书写创建这个类的代码了,代码如下:
代码1:
package create;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class CreateClass implements Opcodes{
public static void createClass() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{
ClassWriter cw = new ClassWriter(0);
//Opcodes.V1_6指定类的版本
//Opcodes.ACC_PUBLIC表示这个类是public,
//“test/Person”类的全限定名称
//第一个null位置变量定义的是泛型签名,
//“java/lang/Object”这个类的父类
//第二个null位子的变量定义的是这个类实现的接口
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "test/Person", null, "java/lang/Object", null);
ClassVisitor cv = new CreateClassAdapter(cw);
cv.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null).visitCode();;
cv.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null).visitCode();;
cv.visitMethod(ACC_PUBLIC, "setName", "(Ljava/lang/String;)V", null, null).visitCode();;
cv.visitEnd();
byte[] code = cw.toByteArray();
MyClassLoader classLo