当前位置:首页 > 科技  > 软件

字节码增强技术,不止有 Java Proxy、 Cglib 和 Javassist 还有 Byte Buddy

来源: 责编: 时间:2024-02-01 12:51:52 368观看
导读提到字节码增强技术,相信用过 Spring 的小伙伴都会知道 Java Proxy 和 Cglib。毕竟面试准备的八股文中说过,Spring 的动态代理有两种实现方式,在有接口存在的时候使用 Java Proxy,当没有接口的时候使用的是 Cglib。这两种

提到字节码增强技术,相信用过 Spring 的小伙伴都会知道 Java Proxy 和 Cglib。suJ28资讯网——每日最新资讯28at.com

毕竟面试准备的八股文中说过,Spring 的动态代理有两种实现方式,在有接口存在的时候使用 Java Proxy,当没有接口的时候使用的是 Cglib。suJ28资讯网——每日最新资讯28at.com

这两种方式的区别不在本文的讨论范围之内,今天想给大家介绍了是另一个字节码增强技术 Byte Buddy。suJ28资讯网——每日最新资讯28at.com

Byte Buddy

根据 Byte Buddy 官网所说,Byte Buddy 是一个代码生成和操作库,用于在 Java 应用程序运行时创建和修改 Java 类,而无需编译器的帮助。suJ28资讯网——每日最新资讯28at.com

Byte Buddy 提供一套简单易用的 API,可以很方便的使用 Java 流式编程的形式来动态创建类或者创建接口的实现类,这一点跟 Java Proxy 和 Cglib 不一样。suJ28资讯网——每日最新资讯28at.com

使用 Byte Buddy 的方式也非常简单,只要直接引入 Maven 依赖即可,没有其他繁琐的依赖。总的来说,使用 Byte Buddy 有下面的优势:suJ28资讯网——每日最新资讯28at.com

  1. 无需理解字节码格式,简单易用的 API 能很容易操作字节码;
  2. 支持 Java 任何版本,库轻量,仅取决于 Java 字节代码解析器库 ASM 的访问者 API,它本身不需要任何其他依赖项。
  3. 比起 JDK 动态代理、cglib、Javassist,Byte Buddy 在性能上具有优势。

图片图片suJ28资讯网——每日最新资讯28at.com

这一份测试报告是官网提供的,表中的每一行分别为,类的创建、接口实现、方法调用、类型扩展、父类方法调用的性能结果。suJ28资讯网——每日最新资讯28at.com

从性能报告中可以看出,Byte Buddy 在一些场景是有优势的,但是在有些场景也不见得特别有优势,不过整体来看还是不错的。suJ28资讯网——每日最新资讯28at.com

测试

说了那么多,下面给大家演示一下,如果使用 Byte Buddy,首先我们需要引入 Maven 依赖,我这里用的版本是 1.14.6,也可以使用其他版本。suJ28资讯网——每日最新资讯28at.com

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

创建一个类,并覆盖 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);        }    }

整个代码的思路是通过 Byte Buddy,构造出一个 Class 对象,然后调用 Class 对象的 newInstance() 方法,再执行 toString() 方法。上面两个方式的功能是一样的,写出来更方便大家理解。suJ28资讯网——每日最新资讯28at.com

其中各个方法的含义如下:suJ28资讯网——每日最新资讯28at.com

subClass:表示构造的类是 Object 的子类;suJ28资讯网——每日最新资讯28at.com

method:表示要构造的具体方法,类似于过滤的功能;suJ28资讯网——每日最新资讯28at.com

intercept:表示对过滤后的方法进行拦截;suJ28资讯网——每日最新资讯28at.com

FixedValue.value("Hello World!"):表示构造返回一个”Hello World!“ 字符串;suJ28资讯网——每日最新资讯28at.com

make:创建 DynamicType.Unloaded 对象,此时这个对象被构造出来,但是还没有被 JVM 加载,还不能使用;suJ28资讯网——每日最新资讯28at.com

load,getLoaded:加载当前类的构造器,并进行加载;suJ28资讯网——每日最新资讯28at.com

等到加载到 JVM 过后,就可以使用 newInstance().toString() 进行调用了。suJ28资讯网——每日最新资讯28at.com

代理方法

上面的例子是创建一个简单的类和方法,下面我们介绍一个代理方法的使用,这里我们有一个目标类 Target 和一个方法 saySomething() 方法,有一个代理类 Agent,里面有一个代理方法 agentSaySomething(),如下所示:suJ28资讯网——每日最新资讯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 字节码写入文件中            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();    }

运行过后我们可以看到生成了一个 class 文件,通过查看代码如下,可以看到是创建了一个 Target 的子类,并且调用了 Agent 的 agentSaySomething 方法。suJ28资讯网——每日最新资讯28at.com

图片图片suJ28资讯网——每日最新资讯28at.com

总结

Byte Buddy的 API 很丰富,这里只是很简单的给大家使用了几个 API,还有包括方法,字段的设定等等,感兴趣的小伙伴可以继续去学习学习。suJ28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-70468-0.html字节码增强技术,不止有 Java Proxy、 Cglib 和 Javassist 还有 Byte Buddy

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Spring Boot项目集成RabbitMQ实战以及坑点讲解

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

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • Mate60手机壳曝光 致敬自己的经典设计

    8月3日消息,今天下午博主数码闲聊站带来了华为Mate60的第三方手机壳图,可以让我们在真机发布之前看看这款华为全新旗舰的大致轮廓。从曝光的图片看,Mate 60背后摄像头面积依然
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 《英雄联盟》夏季赛总决赛今日开打!JDG对阵LNG首发名单来了 Knight:准备三连冠

    8月5日消息,今日17:00,《英雄联盟》2023LPL夏季赛总决赛将正式开打,由JDG对阵LNG。对两支队伍来说,这场比赛不仅要争夺夏季赛冠军,更要决定谁才是LPL赛区一
  • 2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 疑似小米14外观设计图曝光:后置相机模组变化不大

    下半年的大幕已经开启,而谁将成为下半年手机圈的主角就成为了大家关注的焦点,其中被传有望拿下新一代骁龙8 Gen3旗舰芯片的小米14系列更是备受大家瞩
  • 亲历马斯克血洗Twitter,硅谷的苦日子在后头

    文/刘哲铭  编辑/李薇  马斯克再次挥下裁员大刀。  美国时间11月14日,Twitter约4400名外包员工遭解雇,此次被解雇的员工的主要工作为内容审核等。此前,T
Top