ASM 系列詳細教程-01-ASM 入門案例詳細教程

ASM

ASM 是一個通用的Java字節碼操作和分析框架。

它可以用來修改現有的類或動態地生成類,直接以二進制形式。

ASM提供了一些通用的字節碼轉換和分析算法,可以從這些算法中構建自定義複雜的轉換和代碼分析工具。

ASM提供與其他Java字節碼框架類似的功能,但主要關注性能。

因爲它的設計和實現都儘可能地小和快,所以非常適合在動態系統中使用(當然也可以以靜態的方式使用,例如在編譯器中)。

特性

ASM 並不是生成和轉換已編譯Java類的唯一工具,但它是最近和最有效的工具之一。

可以從 http://asm.objectweb.org 下載。其主要優點有:

  • 它有一個簡單、設計良好、模塊化的API,易於使用。

  • 爲最新的 Java 版本提供支持。

  • 它很小,速度很快,而且非常健壯。

  • 其龐大的用戶社區可以爲新用戶提供支持。

  • 它的開放源碼許可允許你以任何你想要的方式使用它。

專題學習目錄

ASM 系列詳細教程-01-ASM 入門簡介

ASM 系列詳細教程-02-ASM 整體概覽

ASM 系列詳細教程-03-ASM 類文件深入學習

ASM 系列詳細教程-04-ASM interface and components 接口和組件

ASM 系列詳細教程-05-ASM class 工具類

ASM 系列詳細教程-06-ASM method struct 方法結構

ASM 系列詳細教程-07-ASM 方法接口與組件

ASM 系列詳細教程-08-ASM 方法工具類

ASM 系列詳細教程-09-ASM 方法增強 aop 字節碼實戰

ASM 系列詳細教程-10-ASM metadata 元數據之泛型

ASM 系列詳細教程-11-ASM metadata 元數據之註解 annotation

ASM 系列詳細教程-12-ASM metadata 元數據之調試 debug

ASM 系列詳細教程-13-ASM core api 向後兼容

ASM 系列詳細教程-14-ASM core api 向後兼容守則

ASM 系列詳細教程-15-ASM ReflectASM 入門案例詳細介紹及實戰

ASM 系列詳細教程-16-ASM Tree api 類接口與組件

ASM 系列詳細教程-17-ASM Tree api 類組件組成詳解

ASM 系列詳細教程-18-ASM Tree api 方法接口與組件

ASM 系列詳細教程-19-ASM Tree api 方法組件組成

ASM 系列詳細教程-20-ASM Method 方法分析介紹

ASM 系列詳細教程-21-ASM Method 方法分析接口與組件

ASM 系列詳細教程-22-ASM Metadata 元數據 Generic Annotation Debug

ASM 系列詳細教程-23-ASM Tree API 向後兼容能力

快速入門

jar 引入

<dependency>
	<groupId>org.ow2.asm</groupId>
	<artifactId>asm-all</artifactId>
	<version>5.1</version>
</dependency>

Hello World

  • HelloWorld.java
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

import java.io.FileOutputStream;
import java.io.PrintStream;

/**
 * <p> </p>
 *
 * <pre> Created: 2018/7/20 下午2:01  </pre>
 * <pre> Project: asm  </pre>
 *
 * @author houbinbin
 * @version 1.0
 * @since JDK 1.7
 */
public class Bean extends ClassLoader implements Opcodes {

    public static void main(final String args[]) throws Exception {
        // creates a ClassWriter for the Example public class,
        // which inherits from Object

        ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
                null);
        mw.visitVarInsn(ALOAD, 0);
        mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mw.visitInsn(RETURN);
        mw.visitMaxs(1, 1);
        mw.visitEnd();
        mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",
                "([Ljava/lang/String;)V", null, null);
        mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                "Ljava/io/PrintStream;");
        mw.visitLdcInsn("Hello world!");
        mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                "(Ljava/lang/String;)V");
        mw.visitInsn(RETURN);
        mw.visitMaxs(2, 2);
        mw.visitEnd();
        byte[] code = cw.toByteArray();
        FileOutputStream fos = new FileOutputStream("Example.class");
        fos.write(code);
        fos.close();
        Bean loader = new Bean();
        Class exampleClass = loader
                .defineClass("Example", code, 0, code.length);
        exampleClass.getMethods()[0].invoke(null, new Object[]{null});

        // ------------------------------------------------------------------------
        // Same example with a GeneratorAdapter (more convenient but slower)
        // ------------------------------------------------------------------------

        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
        Method m = Method.getMethod("void <init> ()");
        GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,
                cw);
        mg.loadThis();
        mg.invokeConstructor(Type.getType(Object.class), m);
        mg.returnValue();
        mg.endMethod();
        m = Method.getMethod("void main (String[])");
        mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
        mg.getStatic(Type.getType(System.class), "out", Type
                .getType(PrintStream.class));
        mg.push("Hello world!");
        mg.invokeVirtual(Type.getType(PrintStream.class), Method
                .getMethod("void println (String)"));
        mg.returnValue();
        mg.endMethod();
        cw.visitEnd();
        code = cw.toByteArray();
        loader = new Bean();
        exampleClass = loader.defineClass("Example", code, 0, code.length);
        exampleClass.getMethods()[0].invoke(null, new Object[]{null});
    }

}

拓展閱讀

更多技術文章,生活趣事,盡在【老馬嘯西風】。

老馬嘯西風

應用實戰

ASM-Tool

基於 ASM 實現比 Spring BeanUtil.copyProperties 性能更好的拷貝框架

參考文檔

快速入門

ASM介紹及簡易教程

發佈了481 篇原創文章 · 獲贊 73 · 訪問量 593萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章