使用Asm操作java字节码(一)

         asm是一款很优秀的操作java字节码的框架,专注于性能,是实现Aop的一大利器,spring中的cglib中的cglib就是使用的asm来完成aop的功能。

         asm中有两种操作字节码的方式,一种是基于事件模型,一种是树模型(对象)。基于事件模型中有几个很核心的类,例如ClassReader,ClassWriter,ClassVisitor。读取一个类的字节码文件,需要使用ClassReader,创建一个类的字节码文件,需要使用ClassWriter,对一个类进行修改需要使用ClassVisitor,通过观察模式进行改变。

         先来一个读取类的字节码文件的例子。

         pom中引入asm的依赖


        
            org.ow2.asm
            asm
            5.0.4
        

         要读取的类Test

         

public class Test {
    
    private Integer id;
    
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

        读取程序

  

public class ClassPrinter extends ClassVisitor {


    public ClassPrinter() {
        super(ASM4);
    }

    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        System.out.println(name+" extend "+superName +" implements "+interfaces);
    }

    @Override
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        System.out.println(" "+descriptor+" "+name);
        return null;
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        System.out.println(" "+name+descriptor);
        return null;
    }

    public static void main(String[] args) throws IOException {
        ClassPrinter classPrinter=new ClassPrinter();

        InputStream cl=ClassLoader.getSystemResourceAsStream(Test.class.getName().replace(".","/")+".class");
        ClassReader classReader=new ClassReader(cl);

        classReader.accept(classPrinter,0);
    }
}

  输出

  

com/example/demo/util/Test extend java/lang/Object implements [Ljava.lang.String;@b4c966a
 Ljava/lang/Integer; id
 Ljava/lang/String; name
 ()V
 getId()Ljava/lang/Integer;
 setId(Ljava/lang/Integer;)V
 getName()Ljava/lang/String;
 setName(Ljava/lang/String;)V

 

你可能感兴趣的:(asm,java)