一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java字節碼的增強技術

Java字節碼的增強技術

2021-12-10 11:06阿凡盧 Java教程

這篇文章簡單介紹了幾種Java字節碼的增強技術,如ASM、Javassist、Byte Buddy、JVM-SANDBOX,需要的朋友可以參下面文章

Java字節碼的增強技術

一、簡單介紹下幾種java字節碼增強技術

1、ASM

ASM是一個Java字節碼操控框架,它能被用來動態生成類或者增強既有類的功能。ASM可以直接產生class文件,也可以在類被加載入Java虛擬機之前動態改變類行為。ASM從類文件中讀入信息后,能夠改變類行為,分析類信息,甚至能夠根據用戶要求生成新類。

ASM框架中的核心類有以下幾個:

  ①  ClassReader:該類用來解析編譯過的class字節碼文件。

  ②  ClassWriter:該類用來重新構建編譯后的類,比如說修改類名、屬性以及方法,甚至可以生成新的類的字節碼文件。

  ③  ClassAdapter:該類也實現了ClassVisitor接口,它將對它的方法調用委托給另一個ClassVisitor對象。

參考代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
 
public class GeneratorClass {
 
    public static void main(String[] args) throws IOException {
        //生成一個類只需要ClassWriter組件即可
        ClassWriter cw = new ClassWriter(0);
        //通過visit方法確定類的頭部信息
        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT+Opcodes.ACC_INTERFACE,
                "com/asm3/Comparable", null, "java/lang/Object", new String[]{"com/asm3/Mesurable"});
        //定義類的屬性
        cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
                "LESS", "I", null, new Integer(-1)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
                "EQUAL", "I", null, new Integer(0)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
                "GREATER", "I", null, new Integer(1)).visitEnd();
        //定義類的方法
        cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "compareTo",
                "(Ljava/lang/Object;)I", null, null).visitEnd();
        cw.visitEnd(); //使cw類已經完成
        //將cw轉換成字節數組寫到文件里面去
        byte[] data = cw.toByteArray();
        File file = new File("D://Comparable.class");
        FileOutputStream fout = new FileOutputStream(file);
        fout.write(data);
        fout.close();
    }
}

2、Javassist

Javassist是一個開源的分析、編輯和創建Java字節碼的類庫。

它已加入了開放源代碼JBoss應用服務器項目,通過使用Javassist對字節碼操作為JBoss實現動態"AOP"框架。

利用Javassist實現字節碼增強時,可以無須關注字節碼刻板的結構,其優點就在于編程簡單。直接使用java編碼的形式,而不需要了解虛擬機指令,就能動態改變類的結構或者動態生成類。其中最重要的是ClassPool、CtClass、CtMethod、CtField這四個類:

  • CtClass(compile-time class):編譯時類信息,它是一個class文件在代碼中的抽象表現形式,可以通過一個類的全限定名來獲取一個CtClass對象,用來表示這個類文件。
  • ClassPool:從開發視角來看,ClassPool是一張保存CtClass信息的HashTable,key為類名,value為類名對應的CtClass對象。當我們需要對某個類進行修改時,就是通過pool.getCtClass(“className”)方法從pool中獲取到相應的CtClass。
  • CtMethod、CtField:這兩個比較好理解,對應的是類中的方法和屬性。

參考代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import javassist.*;
 
public class CreatePerson {
 
    public static void createPseson() throws Exception {
        ClassPool pool = ClassPool.getDefault();
 
        // 1. 創建一個空類
        CtClass cc = pool.makeClass("com.test.javassist.Person");
 
        // 2. 新增一個字段 private String name;
        // 字段名為name
        CtField param = new CtField(pool.get("java.lang.String"), "name", cc);
        // 訪問級別是 private
        param.setModifiers(Modifier.PRIVATE);
        // 初始值是 "xiaoming"
        cc.addField(param, CtField.Initializer.constant("xiaoming"));
 
        // 3. 生成 getter、setter 方法
        cc.addMethod(CtNewMethod.setter("setName", param));
        cc.addMethod(CtNewMethod.getter("getName", param));
 
        // 4. 添加無參的構造函數
        CtConstructor cons = new CtConstructor(new CtClass[]{}, cc);
        cons.setBody("{name = \"xiaohong\";}");
        cc.addConstructor(cons);
 
        // 5. 添加有參的構造函數
        cons = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, cc);
        // $0=this / $1,$2,$3... 代表方法參數
        cons.setBody("{$0.name = $1;}");
        cc.addConstructor(cons);
 
        // 6. 創建一個名為printName方法,無參數,無返回值,輸出name值
        CtMethod ctMethod = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, cc);
        ctMethod.setModifiers(Modifier.PUBLIC);
        ctMethod.setBody("{System.out.println(name);}");
        cc.addMethod(ctMethod);
 
        //這里會將這個創建的類對象編譯為.class文件
        cc.writeFile("/Users/yangyue/workspace/springboot-learn/java-agent/src/main/java/");
    }
 
    public static void main(String[] args) {
        try {
            createPseson();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、Byte Buddy

Byte Buddy是一個代碼生成和操作庫,用于在Java應用程序運行時創建和修改Java類,而無需編譯器的幫助。
除了Java類庫附帶的代碼生成實用程序外,Byte Buddy還允許創建任意類,并且不限于實現用于創建運行時代理的接口。
此外,Byte Buddy提供了一種方便的API,可以使用Java代理或在構建過程中手動更改類。

參考代碼:

?
1
2
3
4
5
6
7
8
9
Class<?> dynamicType = new ByteBuddy()
  .subclass(Object.class)
  .method(ElementMatchers.named("toString"))
  .intercept(FixedValue.value("Hello World!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();
 
assertThat(dynamicType.newInstance().toString(), is("Hello World!"));

4、JVM-SANDBOX

JVM沙箱容器,一種JVM的非侵入式運行期AOP解決方案:

動態增強類你所指定的類,獲取你想要的參數和行信息甚至改變方法執行。
動態可插拔容器框架。

到此這篇關于Java字節碼的增強技術的文章就介紹到這了,更多相關Java字節碼增強內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/luxiaoxun/p/15075778.html

延伸 · 閱讀

精彩推薦
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
主站蜘蛛池模板: 国产成人精品免费2021 | 欧美性高清另类videosex死尸 | 韩国日本在线观看 | 亚洲精品中文字幕在线 | 国产精品久久久久久福利 | 好奇害死猫在线观看 | 国产精品久久久久久久久久久久 | 婷婷综合缴情亚洲五月伊 | 超逼网| 国产亚洲精品久久yy5099 | 国产视频一二三区 | 美女女女女女女bbbbbb毛片 | 好大好湿好硬好爽好深免费视频 | 国产激情一区二区三区四区 | 久久精品中文字幕 | 天天操天天爽天天射 | 色综合天天综合网国产人 | 亚洲精品在线网址 | 狠狠色婷婷狠狠狠亚洲综合 | 青春草在线观看视频 | 色综合综合色 | 高清色黄毛片一级毛片 | 美女用手扒开粉嫩的屁股 | 肥胖女性大bbbbbb视频女厕 | 免费日批 | 国产乱码免费卡1卡二卡3卡四 | 亚洲视频在线看 | 精品精品久久宅男的天堂 | 鞋奴的视频VK | 久久91精品国产91久 | 99综合视频 | 滑进了柔佳火热紧夹的 | 性欧美xxxxx老太婆 | 美女靠逼免费视频 | 男男互操文 | 国产精品免费一级在线观看 | 成年人视频免费在线观看 | 美女把小内内脱个精光打屁屁 | 国产欧美日韩免费一区二区 | 国产欧美日韩综合 | 日本中文字幕永久在线 |