亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java字節(jié)碼增強(qiáng)技術(shù)知識(shí)點(diǎn)詳解

 更新時(shí)間:2021年08月01日 15:31:52   作者:阿凡盧  
在本篇文章里小編給大家整理的是一篇關(guān)于Java字節(jié)碼增強(qiáng)技術(shù)知識(shí)點(diǎn)詳解內(nèi)容,有興趣的朋友可以跟著學(xué)習(xí)下。

簡(jiǎn)單介紹下幾種java字節(jié)碼增強(qiáng)技術(shù)。

ASM

ASM是一個(gè)Java字節(jié)碼操控框架,它能被用來(lái)動(dòng)態(tài)生成類(lèi)或者增強(qiáng)既有類(lèi)的功能。ASM可以直接產(chǎn)生class文件,也可以在類(lèi)被加載入Java虛擬機(jī)之前動(dòng)態(tài)改變類(lèi)行為。ASM從類(lèi)文件中讀入信息后,能夠改變類(lèi)行為,分析類(lèi)信息,甚至能夠根據(jù)用戶要求生成新類(lèi)。

主頁(yè):https://asm.ow2.io/index.html

ASM框架中的核心類(lèi)有以下幾個(gè):

① ClassReader:該類(lèi)用來(lái)解析編譯過(guò)的class字節(jié)碼文件。

② ClassWriter:該類(lèi)用來(lái)重新構(gòu)建編譯后的類(lèi),比如說(shuō)修改類(lèi)名、屬性以及方法,甚至可以生成新的類(lèi)的字節(jié)碼文件。

③ ClassAdapter:該類(lèi)也實(shí)現(xiàn)了ClassVisitor接口,它將對(duì)它的方法調(diào)用委托給另一個(gè)ClassVisitor對(duì)象。

參考代碼:

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 {
        //生成一個(gè)類(lèi)只需要ClassWriter組件即可
        ClassWriter cw = new ClassWriter(0);
        //通過(guò)visit方法確定類(lèi)的頭部信息
        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"});
        //定義類(lèi)的屬性
        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();
        //定義類(lèi)的方法
        cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "compareTo",
                "(Ljava/lang/Object;)I", null, null).visitEnd();
        cw.visitEnd(); //使cw類(lèi)已經(jīng)完成
        //將cw轉(zhuǎn)換成字節(jié)數(shù)組寫(xiě)到文件里面去
        byte[] data = cw.toByteArray();
        File file = new File("D://Comparable.class");
        FileOutputStream fout = new FileOutputStream(file);
        fout.write(data);
        fout.close();
    }
}

Javassist

Javassist是一個(gè)開(kāi)源的分析、編輯和創(chuàng)建Java字節(jié)碼的類(lèi)庫(kù)。

它已加入了開(kāi)放源代碼JBoss應(yīng)用服務(wù)器項(xiàng)目,通過(guò)使用Javassist對(duì)字節(jié)碼操作為JBoss實(shí)現(xiàn)動(dòng)態(tài)"AOP"框架。

主頁(yè):http://www.javassist.org/

利用Javassist實(shí)現(xiàn)字節(jié)碼增強(qiáng)時(shí),可以無(wú)須關(guān)注字節(jié)碼刻板的結(jié)構(gòu),其優(yōu)點(diǎn)就在于編程簡(jiǎn)單。直接使用java編碼的形式,而不需要了解虛擬機(jī)指令,就能動(dòng)態(tài)改變類(lèi)的結(jié)構(gòu)或者動(dòng)態(tài)生成類(lèi)。其中最重要的是ClassPool、CtClass、CtMethod、CtField這四個(gè)類(lèi):

CtClass(compile-time class):編譯時(shí)類(lèi)信息,它是一個(gè)class文件在代碼中的抽象表現(xiàn)形式,可以通過(guò)一個(gè)類(lèi)的全限定名來(lái)獲取一個(gè)CtClass對(duì)象,用來(lái)表示這個(gè)類(lèi)文件。

ClassPool:從開(kāi)發(fā)視角來(lái)看,ClassPool是一張保存CtClass信息的HashTable,key為類(lèi)名,value為類(lèi)名對(duì)應(yīng)的CtClass對(duì)象。當(dāng)我們需要對(duì)某個(gè)類(lèi)進(jìn)行修改時(shí),就是通過(guò)pool.getCtClass(“className”)方法從pool中獲取到相應(yīng)的CtClass。

CtMethod、CtField:這兩個(gè)比較好理解,對(duì)應(yīng)的是類(lèi)中的方法和屬性。

參考代碼:

import javassist.*;

public class CreatePerson {

    public static void createPseson() throws Exception {
        ClassPool pool = ClassPool.getDefault();

        // 1. 創(chuàng)建一個(gè)空類(lèi)
        CtClass cc = pool.makeClass("com.test.javassist.Person");

        // 2. 新增一個(gè)字段 private String name;
        // 字段名為name
        CtField param = new CtField(pool.get("java.lang.String"), "name", cc);
        // 訪問(wèn)級(jí)別是 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. 添加無(wú)參的構(gòu)造函數(shù)
        CtConstructor cons = new CtConstructor(new CtClass[]{}, cc);
        cons.setBody("{name = \"xiaohong\";}");
        cc.addConstructor(cons);

        // 5. 添加有參的構(gòu)造函數(shù)
        cons = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, cc);
        // $0=this / $1,$2,$3... 代表方法參數(shù)
        cons.setBody("{$0.name = $1;}");
        cc.addConstructor(cons);

        // 6. 創(chuàng)建一個(gè)名為printName方法,無(wú)參數(shù),無(wú)返回值,輸出name值
        CtMethod ctMethod = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, cc);
        ctMethod.setModifiers(Modifier.PUBLIC);
        ctMethod.setBody("{System.out.println(name);}");
        cc.addMethod(ctMethod);

        //這里會(huì)將這個(gè)創(chuàng)建的類(lèi)對(duì)象編譯為.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();
        }
    }
}

Byte Buddy

Byte Buddy是一個(gè)代碼生成和操作庫(kù),用于在Java應(yīng)用程序運(yùn)行時(shí)創(chuàng)建和修改Java類(lèi),而無(wú)需編譯器的幫助。
除了Java類(lèi)庫(kù)附帶的代碼生成實(shí)用程序外,Byte Buddy還允許創(chuàng)建任意類(lèi),并且不限于實(shí)現(xiàn)用于創(chuàng)建運(yùn)行時(shí)代理的接口。
此外,Byte Buddy提供了一種方便的API,可以使用Java代理或在構(gòu)建過(guò)程中手動(dòng)更改類(lèi)。

主頁(yè):https://bytebuddy.net/

參考代碼:

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!"));

JVM-SANDBOX

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

動(dòng)態(tài)增強(qiáng)類(lèi)你所指定的類(lèi),獲取你想要的參數(shù)和行信息甚至改變方法執(zhí)行。

動(dòng)態(tài)可插拔容器框架。
主頁(yè):https://github.com/alibaba/jvm-sandbox

知識(shí)點(diǎn)擴(kuò)充:

動(dòng)態(tài)生成字節(jié)碼

我們知道,我們編寫(xiě)的 Java 代碼都是要被編譯成字節(jié)碼后才能放到 JVM 里執(zhí)行的,而字節(jié)碼一旦被加載到虛擬機(jī)中,就可以被解釋執(zhí)行。

字節(jié)碼文件(.class)就是普通的二進(jìn)制文件,它是通過(guò) Java 編譯器生成的。而只要是文件就可以被改變,如果我們用特定的規(guī)則解析了原有的字節(jié)碼文件,對(duì)它進(jìn)行修改或者干脆重新定義,這不就可以改變代碼行為了么。

Java 生態(tài)里有很多可以動(dòng)態(tài)生成字節(jié)碼的技術(shù),像 BCEL、Javassist、ASM、CGLib 等,它們各有自己的優(yōu)勢(shì)。有的使用復(fù)雜卻功能強(qiáng)大、有的簡(jiǎn)單確也性能些差。

ASM 框架

ASM 是它們中最強(qiáng)大的一個(gè),使用它可以動(dòng)態(tài)修改類(lèi)、方法,甚至可以重新定義類(lèi),連 CGLib 底層都是用 ASM 實(shí)現(xiàn)的。

當(dāng)然,它的使用門(mén)檻也很高,使用它需要對(duì) Java 的字節(jié)碼文件有所了解,熟悉 JVM 的編譯指令。雖然我對(duì) JVM 的字節(jié)碼語(yǔ)法不熟,但有大神開(kāi)發(fā)了可以在 IDEA 里查看字節(jié)碼的插件:ASM Bytecode Outline,在要查看的類(lèi)文件里右鍵選擇Show bytecode Outline即可以右側(cè)的工具欄查看我們要生成的字節(jié)碼。對(duì)照著示例,我們就可以很輕松地寫(xiě)出操作字節(jié)碼的 Java 代碼了。

到此這篇關(guān)于Java字節(jié)碼增強(qiáng)技術(shù)知識(shí)點(diǎn)詳解的文章就介紹到這了,更多相關(guān)Java字節(jié)碼增強(qiáng)技術(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java計(jì)算自?xún)鐢?shù)和水仙花數(shù)

    java計(jì)算自?xún)鐢?shù)和水仙花數(shù)

    對(duì)于一個(gè)正整數(shù)而言,長(zhǎng)度是n,如果它的各位上的數(shù)字的n次方之和正好等于它本身,那么我們稱(chēng)這樣的數(shù)為自?xún)鐢?shù),下面使用JAVA實(shí)現(xiàn)這個(gè)方法
    2014-03-03
  • Spring?AOP中的環(huán)繞通知詳解

    Spring?AOP中的環(huán)繞通知詳解

    AOP是一種思想,是對(duì)某一類(lèi)事情的集中處理,接下來(lái)我們要學(xué)習(xí)的是運(yùn)用了AOP思想,進(jìn)行AOP的環(huán)繞處理,本文通過(guò)實(shí)例講解Spring?AOP中的環(huán)繞通知,感興趣的朋友一起看看吧
    2024-07-07
  • mybatis-plus  mapper中foreach循環(huán)操作代碼詳解(新增或修改)

    mybatis-plus mapper中foreach循環(huán)操作代碼詳解(新增或修改)

    這篇文章主要介紹了mybatis-plus mapper中foreach循環(huán)操作代碼詳解(新增或修改),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用

    SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用

    OpenFeign對(duì)feign進(jìn)行進(jìn)一步的封裝,添加了springmvc的一些功能,更加強(qiáng)大,下面這篇文章主要給大家介紹了關(guān)于SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • java編程簡(jiǎn)單獲取圖片像素的方法

    java編程簡(jiǎn)單獲取圖片像素的方法

    這篇文章主要介紹了java編程簡(jiǎn)單獲取圖片像素的方法,涉及Java針對(duì)圖片的讀取與屬性獲取技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情

    Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情

    這篇文章主要介紹了Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • Python__雙劃線參數(shù)代碼實(shí)例解析

    Python__雙劃線參數(shù)代碼實(shí)例解析

    這篇文章主要介紹了python__雙劃線參數(shù)代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot整合mybatis-generator-maven-plugin的方法

    SpringBoot整合mybatis-generator-maven-plugin的方法

    這篇文章主要介紹了SpringBoot整合mybatis-generator-maven-plugin,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • springMvc注解之@ResponseBody和@RequestBody詳解

    springMvc注解之@ResponseBody和@RequestBody詳解

    本篇文章主要介紹了springMvc注解之@ResponseBody和@RequestBody詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Java設(shè)計(jì)模式之組合模式

    Java設(shè)計(jì)模式之組合模式

    這篇文章介紹了Java設(shè)計(jì)模式之組合模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09

最新評(píng)論