net.bytebuddy字节码引擎,动态生成Java类

Net ByteBuddy 是 Java 世界里"运行时动态生成字节码"的一把瑞士军刀------

官方口号:"Code like a Pro, intercept like a Boss."

用纯 API 就能在 "零编译、零源码" 的前提下:

  • 动态创建子类 / 接口实现
  • 拦截(改写)任意方法(包括 final、static、private)
  • 给类加字段、加注解、加接口
  • 生成 Lambda、访问者、代理、AOP 切面、Mock 桩......

而且语法像 fluent-builder,写起来比手写 ASM 舒服 10 倍,性能又比 CGLib / Javassist 高一头;

Spring Framework 5.3+、Mockito 2+、Hibernate 6 都把它当默认字节码引擎。


一句话定位

"ByteBuddy = ASM 的脚手架 + CGLib 的易用性 + Java-Agent 的侵入能力"


核心概念(中文速记)

英文术语 白话解释 对应代码入口
ByteBuddy 工厂大吊车,一切动态类型的起点 new ByteBuddy()
DynamicType 正在"搭建"的类,还没落盘 .subclass(Xxx.class)
ElementMatcher "谁"要被拦截------方法/字段/注解过滤 ElementMatchers.any()
Implementation 拦截后"怎么干"------固定值、调用父类、转发、自定义 MethodDelegation.to(MyInterceptor.class)
Unloaded 已生成字节码但未加载,可 .saveIn() 落盘调试 dynamicType.make()
Loaded 已经进 JVM 的 Class,可直接 newInstance() type.load(getClass().getClassLoader())

10 行代码速通(动态子类 + 方法拦截)

xml 复制代码
		<dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.14.16</version>
        </dependency>
java 复制代码
// 1. 定义拦截器:所有方法都转发到这里
public class TimeInterceptor {
    @RuntimeType
    public Object intercept(@Origin Method method,
                            @SuperCall Callable<?> zuper) throws Exception {
        long start = System.nanoTime();
        try { return zuper.call(); }          // 继续原实现
        finally { System.out.println(method + " 耗时 " + (System.nanoTime()-start)/1_000_000 + " ms"); }
    }
}

// 2. 运行时生成子类并加载
Class<? extends ArrayList> dynamicType = new ByteBuddy()
        .subclass(ArrayList.class)                       // 我要继承 ArrayList
        .method(ElementMatchers.any())                   // 拦截所有方法
        .intercept(MethodDelegation.to(TimeInterceptor.class))
        .make()
        .load(getClass().getClassLoader())
        .getLoaded();

// 3. 像正常类一样用
List<String> list = dynamicType.getDeclaredConstructor().newInstance();
list.add("byte");
list.add("buddy");
System.out.println(list);   // 输出内容 + 每方法耗时

常见玩法地图

  1. 给接口快速生成实现类(MyBatis Mapper 那种)

    java 复制代码
    new ByteBuddy()
        .implement(UserMapper.class)
        .intercept(MethodDelegation.to(sqlSession));
  2. 运行时重新加载已存在的类(Java-Agent 热补丁)

    java 复制代码
    ByteBuddyAgent.install();          // attach 到当前 JVM
    new ByteBuddy()
        .redefine(FooService.class)
        .method(named("calc")).intercept(FixedValue.value(42))
        .installOnByteBuddyAgent();
  3. 生成 Lambda 的"元工厂"字节码,提升反射调用速度(Spring 5.3 内部用它替代 CGLib)。

  4. 单元测试 Mock 桩(Mockito 2 默认底层就是 ByteBuddy)。


性能 & 体积

  • 生成速度:首次约 1~3 ms / 类,之后内部缓存 < 0.1 ms。
  • 运行速度:接近手写子类,无反射开销(生成的字节码里直接 invokespecial / invokevirtual)。
  • 依赖体积:核心 byte-buddy-1.14.x.jar 仅 3.5 MB,无 Native 代码。

一句话总结

"只要你会写 fluent API,就能在运行时'凭空'造出任何 Java 类,并让它按你的规则跑------这就是 ByteBuddy。"

相关推荐
Chester_19995 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲6 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员7 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导7 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan7 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251497 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
2601_961901707 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..8 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
大衛說8 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
QQ_21696290969 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端