日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

字節(jié)碼增強(qiáng)技術(shù),不止有 Java Proxy、 Cglib 和 Javassist 還有 Byte Buddy

來(lái)源: 責(zé)編: 時(shí)間:2024-02-01 12:51:52 259觀看
導(dǎo)讀提到字節(jié)碼增強(qiáng)技術(shù),相信用過 Spring 的小伙伴都會(huì)知道 Java Proxy 和 Cglib。畢竟面試準(zhǔn)備的八股文中說(shuō)過,Spring 的動(dòng)態(tài)代理有兩種實(shí)現(xiàn)方式,在有接口存在的時(shí)候使用 Java Proxy,當(dāng)沒有接口的時(shí)候使用的是 Cglib。這兩種

提到字節(jié)碼增強(qiáng)技術(shù),相信用過 Spring 的小伙伴都會(huì)知道 Java Proxy 和 Cglib。0he28資訊網(wǎng)——每日最新資訊28at.com

畢竟面試準(zhǔn)備的八股文中說(shuō)過,Spring 的動(dòng)態(tài)代理有兩種實(shí)現(xiàn)方式,在有接口存在的時(shí)候使用 Java Proxy,當(dāng)沒有接口的時(shí)候使用的是 Cglib。0he28資訊網(wǎng)——每日最新資訊28at.com

這兩種方式的區(qū)別不在本文的討論范圍之內(nèi),今天想給大家介紹了是另一個(gè)字節(jié)碼增強(qiáng)技術(shù) Byte Buddy。0he28資訊網(wǎng)——每日最新資訊28at.com

Byte Buddy

根據(jù) Byte Buddy 官網(wǎng)所說(shuō),Byte Buddy 是一個(gè)代碼生成和操作庫(kù),用于在 Java 應(yīng)用程序運(yùn)行時(shí)創(chuàng)建和修改 Java 類,而無(wú)需編譯器的幫助。0he28資訊網(wǎng)——每日最新資訊28at.com

Byte Buddy 提供一套簡(jiǎn)單易用的 API,可以很方便的使用 Java 流式編程的形式來(lái)動(dòng)態(tài)創(chuàng)建類或者創(chuàng)建接口的實(shí)現(xiàn)類,這一點(diǎn)跟 Java Proxy 和 Cglib 不一樣。0he28資訊網(wǎng)——每日最新資訊28at.com

使用 Byte Buddy 的方式也非常簡(jiǎn)單,只要直接引入 Maven 依賴即可,沒有其他繁瑣的依賴。總的來(lái)說(shuō),使用 Byte Buddy 有下面的優(yōu)勢(shì):0he28資訊網(wǎng)——每日最新資訊28at.com

  1. 無(wú)需理解字節(jié)碼格式,簡(jiǎn)單易用的 API 能很容易操作字節(jié)碼;
  2. 支持 Java 任何版本,庫(kù)輕量,僅取決于 Java 字節(jié)代碼解析器庫(kù) ASM 的訪問者 API,它本身不需要任何其他依賴項(xiàng)。
  3. 比起 JDK 動(dòng)態(tài)代理、cglib、Javassist,Byte Buddy 在性能上具有優(yōu)勢(shì)。

圖片圖片0he28資訊網(wǎng)——每日最新資訊28at.com

這一份測(cè)試報(bào)告是官網(wǎng)提供的,表中的每一行分別為,類的創(chuàng)建、接口實(shí)現(xiàn)、方法調(diào)用、類型擴(kuò)展、父類方法調(diào)用的性能結(jié)果。0he28資訊網(wǎng)——每日最新資訊28at.com

從性能報(bào)告中可以看出,Byte Buddy 在一些場(chǎng)景是有優(yōu)勢(shì)的,但是在有些場(chǎng)景也不見得特別有優(yōu)勢(shì),不過整體來(lái)看還是不錯(cuò)的。0he28資訊網(wǎng)——每日最新資訊28at.com

測(cè)試

說(shuō)了那么多,下面給大家演示一下,如果使用 Byte Buddy,首先我們需要引入 Maven 依賴,我這里用的版本是 1.14.6,也可以使用其他版本。0he28資訊網(wǎng)——每日最新資訊28at.com

<dependency>    <groupId>net.bytebuddy</groupId>    <artifactId>byte-buddy</artifactId>    <version>1.14.6</version></dependency>

創(chuàng)建一個(gè)類,并覆蓋 toString

public static void test1() {        try {            Class<?> dynamicType = new ByteBuddy().                    subclass(Object.class)                    .method(ElementMatchers.named("toString"))                    .intercept(FixedValue.value("Hello World!"))                    .make()                    .load(ByteBuddyDemo.class.getClassLoader())                    .getLoaded();            System.out.println(dynamicType.newInstance().toString());        } catch (Exception e) {            System.out.println(e.getMessage());        }    }public static void test2() {        try {            DynamicType.Unloaded<Object> unloaded = new ByteBuddy()                    .subclass(Object.class)                    .method(ElementMatchers.named("toString"))                    .intercept(FixedValue.value("Hello World!"))                    .make();            DynamicType.Loaded<Object> load = unloaded.load(ByteBuddyDemo.class.getClassLoader());            System.out.println(load.getLoaded().newInstance().toString());        } catch (Exception e) {            throw new RuntimeException(e);        }    }

整個(gè)代碼的思路是通過 Byte Buddy,構(gòu)造出一個(gè) Class 對(duì)象,然后調(diào)用 Class 對(duì)象的 newInstance() 方法,再執(zhí)行 toString() 方法。上面兩個(gè)方式的功能是一樣的,寫出來(lái)更方便大家理解。0he28資訊網(wǎng)——每日最新資訊28at.com

其中各個(gè)方法的含義如下:0he28資訊網(wǎng)——每日最新資訊28at.com

subClass:表示構(gòu)造的類是 Object 的子類;0he28資訊網(wǎng)——每日最新資訊28at.com

method:表示要構(gòu)造的具體方法,類似于過濾的功能;0he28資訊網(wǎng)——每日最新資訊28at.com

intercept:表示對(duì)過濾后的方法進(jìn)行攔截;0he28資訊網(wǎng)——每日最新資訊28at.com

FixedValue.value("Hello World!"):表示構(gòu)造返回一個(gè)”Hello World!“ 字符串;0he28資訊網(wǎng)——每日最新資訊28at.com

make:創(chuàng)建 DynamicType.Unloaded 對(duì)象,此時(shí)這個(gè)對(duì)象被構(gòu)造出來(lái),但是還沒有被 JVM 加載,還不能使用;0he28資訊網(wǎng)——每日最新資訊28at.com

load,getLoaded:加載當(dāng)前類的構(gòu)造器,并進(jìn)行加載;0he28資訊網(wǎng)——每日最新資訊28at.com

等到加載到 JVM 過后,就可以使用 newInstance().toString() 進(jìn)行調(diào)用了。0he28資訊網(wǎng)——每日最新資訊28at.com

代理方法

上面的例子是創(chuàng)建一個(gè)簡(jiǎn)單的類和方法,下面我們介紹一個(gè)代理方法的使用,這里我們有一個(gè)目標(biāo)類 Target 和一個(gè)方法 saySomething() 方法,有一個(gè)代理類 Agent,里面有一個(gè)代理方法 agentSaySomething(),如下所示:0he28資訊網(wǎng)——每日最新資訊28at.com

public class Target {    public String saySomething() {        return "Hello target";    }}public class Agent {    public static String agentSaySomething() {        System.out.println("agentSaySomething");        return "hello agent";    }}public static void test4() {        try {            DynamicType.Unloaded<Target> agent = new ByteBuddy()                    .subclass(Target.class)                    .method(named("saySomething")                            .and(isDeclaredBy(Target.class)                                    .and(returns(String.class))))                    .intercept(MethodDelegation.to(Agent.class))                    .make();            // 將 agent 字節(jié)碼寫入文件中            outputClazz(agent.getBytes());        } catch (Exception e) {            throw new RuntimeException(e);        }    }    private static void outputClazz(byte[] bytes) {        FileOutputStream out = null;        try {            String pathName = ByteBuddyDemo.class.getResource("/").getPath() + "AgentTarget.class";            out = new FileOutputStream(new File(pathName));            System.out.println("類輸出路徑:" + pathName);            out.write(bytes);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != out) try {                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }   public static void main(String[] args) {        test4();    }

運(yùn)行過后我們可以看到生成了一個(gè) class 文件,通過查看代碼如下,可以看到是創(chuàng)建了一個(gè) Target 的子類,并且調(diào)用了 Agent 的 agentSaySomething 方法。0he28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片0he28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

Byte Buddy的 API 很豐富,這里只是很簡(jiǎn)單的給大家使用了幾個(gè) API,還有包括方法,字段的設(shè)定等等,感興趣的小伙伴可以繼續(xù)去學(xué)習(xí)學(xué)習(xí)。0he28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-70468-0.html字節(jié)碼增強(qiáng)技術(shù),不止有 Java Proxy、 Cglib 和 Javassist 還有 Byte Buddy

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Spring Boot項(xiàng)目集成RabbitMQ實(shí)戰(zhàn)以及坑點(diǎn)講解

下一篇: Java的ConcurrentHashMap是使用的分段鎖?

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 开远市| 万全县| 马龙县| 合肥市| 陆河县| 沂水县| 南丹县| 吴忠市| 贞丰县| 商都县| 西安市| 玉山县| 普格县| 石渠县| 安国市| 龙海市| 象州县| 合江县| 瑞丽市| 伽师县| 河津市| 商都县| 区。| 丹凤县| 晋宁县| 镇安县| 吴堡县| 开江县| 德安县| 辰溪县| 祁门县| 西丰县| 鸡泽县| 鹤庆县| 靖宇县| 舞钢市| 辽中县| 临沂市| 临夏市| 密云县| 恩平市|