`

【Java核心-进阶】运行时动态生成Java类

    博客分类:
  • Java
 
阅读更多

技术上可行的方式

生成源码文件 -> 编译源码 -> 加载类

方式1:javac 编译

可以用 ProcessBuilder 这个类启动 javac 进程,编译源码文件

 

方式2:Java Compiler API 编译

JDK中的 Java Compiler API 提供了与 javac 对等的编译能力。(示例:InMemoryJavaCompiler

 

直接生成字节码 -> 加载类

一般通过字节码操作工具和类库来更改Java Class的字节码。
流行的工具有 ASMJavassistcglibByte Buddy 等。
很多工具/框架中的动态代理实现中就有用到这些工具。如,Spring框架内置了 cglib

 

字节码 -> Class

将字节码转换为 Class 发生在类加载过程中(《Java类加载》)。
可通过 ClassLoader.defineClass 方法将字节码转换成Class对象。
或者使用JDK中其它对等的方法(不同版本的JDK会略有不同)。

public abstract class ClassLoader {
  protected final Class<?> defineClass(
      String name, byte[] b, int off, int len,
      ProtectionDomain protectionDomain);

  protected final Class<?> defineClass(
      String name, java.nio.ByteBuffer b,
      ProtectionDomain protectionDomain);

  static native Class<?> defineClass1(
      ClassLoader loader, String name, byte[] b, int off, int len,
      ProtectionDomain pd, String source);

  static native Class<?> defineClass2(
      ClassLoader loader, String name, java.nio.ByteBuffer b,
      int off, int len, ProtectionDomain pd, String source);
  ...
}

 

操作字节码

JDK 动态代理实现方式

JDK动态代理实现的方式是比较hack的,需要了解JVM指令,偏移地址的处理也比较繁琐。
ProxyGenerator 类源码可以看出这种方式的使用门槛非常高,不适合普通开发场景。

 

更抽象方便的类库(ASM等)

JDK内部集成了ASM类库。如,命名空间 jdk.internal.org.objectweb.asm 下的 ClassWriter 类提供了一组用于生成字节码的方法。

public class ClassWriter extends ClassVisitor {
  // 构建 Class 签名(指定Java版本、访问权限、名称、父类、实现接口等)
  public final void visit(
      final int version, final int access, final String name,
      final String signature, final String superName,
      final String[] interfaces);

  // 构建方法
  public final MethodVisitor visitMethod(
      final int access, final String name, final String descriptor,
      final String signature, final String[] exceptions);

  // 结束字节码生成
  public final void visitEnd();

  // 输出字节码,用于前述的 ClassLoader 载入该新建的类
  public byte[] toByteArray();
  ...
}

public abstract class MethodVisitor {
  // 构建方法内部代码
  public void visitCode();
  ...
}

 

ASM中的 Visitor 模式

在生成/修改字节码的大多数场景中,都是依赖特定结构,修改或新增 方法、变量、类型等。
而Visitor模式的优势就是将算法和对象结构解耦,所以ASM API广泛使用了该模式。

 

字节码操作技术的使用场景

大多数业务不会直接使用字节码操作技术,但它是很多工具和底层框架必不可少的部分。
Mock 框架、ORM 框架、IOC 容器、Profiler或运行时诊断工具、形式化代码生成工具 等都会用到字节码操作技术。
 

在一些资源消耗统计的场景中也经常出现字节码操作技术的身影。
如,为了统计某些方法调用的网络通信的消耗,我们可以通过 JavaAgent + 字节码操作技术 来改变相关类,植入统计相关数据的代码。
这种方式不会侵入原业务代码,比AOP的方式更干净。而且不开启统计功能时,是零开销

 

分享到:
评论

相关推荐

    JVM性能优化相关问题-面试-进阶

    Java 类加载需要经历一下 7 个过程: 1. 加载 加载是类加载的第一个过程,在这个阶段,将完成一下三件事情: • 通过一个类的全限定名获取该类的二进制流。 • 将该二进制流中的静态存储结构转化为方法去运行时数据...

    7-java进阶-集合1

    1.生成哈希值,计算存放位置,如果位置为空,直接存放 2.如果位置不为空,调用equals判断内容是否一致,一致则不存放,保证独一无二 3.内容不一致,则以链表

    JNI之Hello-JNI进阶

    2. 编写HelloJni工程,在主Activity(本例:HelloJni.java)里声明native函数: 如下: public native String stringFromJNI(); public native double add(double a, double b); public native double sub...

    Java进阶--深入理解ArrayList实现原理

    ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小。要注意的是ArrayList并不是线程安全的,因此一般建议在单...

    Java进阶学习jar打包详解

    Java进阶学习:jar打包详解  -c 创建新的存档  -t 列出存档内容的列表  -x 展开存档中的命名的(或所有的〕文件  -u 更新已存在的存档  -v 生成详细输出到标准输出上  -f 指定存档文件名  -m 包含...

    Java进阶教程Velocity快速掌握模板引擎视频

    l 全面 : 本课程从基础的velocity engine 讲到进阶的velocity Tools , 从代码生成器到web开发 , 多种使用场景都有涉及 l 版本新 : 本课程讲解是基于最新的 velocity engine 2.2以及velocity Tools 3.0 3. 课程内容 ...

    Java补充实验.doc

    本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...

    JFinal离线文档4.8.pdf

    JFinal文档的离线版本,目前于2020-04-22最新版本的生成。方便无网离线查阅。也给自己留个备份。

    二维码批量生成工具进阶版.zip

    程序使用JAVA语言编写,运行时请确保电脑已安装并配置好JAVA运行环境; 1.新建一个txt格式的文本文档,再将需要生成的二维码的文本 复制到文档中,一行代表一个二维码。 2.单机浏览按钮选择刚刚新建的文本文档,然后...

    JNI技术手册 c/c++调用java

    IV. Java JNI 编程进阶 18 一、 解决性能问题 18 二、 解决本机平台接口调用问题 19 三、 嵌入式开发应用(JNI小例子) 20 1、 新增一个基础类 22 2、 定义新类继承基础类 23 3、 编写调用类 23 4、 新增两个本地方法 ...

    很棒的Java书:Java开发者技术书籍大全-Java入门书籍,Java基础及进阶书籍,框架与中间件,架构设计,设计模式,数学与算法,JVM周边语言,项目管理和领导力与流程,职业素养与个人成长,地形与视野,面试参考书等

    涵盖领域:Java入门书籍,Java基础及进阶书籍,框架与中间件,架构设计,设计模式,数学与算法,JVM周边语言,项目管理和领导力及流程,职业素养与个人成长,布局与视野,面试参考书等。推荐书籍可以点击-&gt;书籍列表-...

    Java-Web程序设计(PPT).pptx

    第1章 Web应用程序基础 Java Web程序设计 Java-Web程序设计(PPT)全文共389页,当前为第1页。 课程概述 终点 起点 1 2 3 4 5 6 7 1.Web应用程序基础 2.JSP基础 3.JSP内置对象 5. Servlet技术 4.JavaBean和标准动作 6....

    基于最新的Java 21和SpringBoot 3.2 根据eladmin项目进行改造+源代码+文档说明

    2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。...

    Java虚拟机指令手册+复习面试题+从入门到进阶完整资源合集

    JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器...

    课程设计-基于Java开发的简易古诗生成器+源代码+文档说明

    2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。...

    java基础案例与开发详解案例源码全

    2.6 Java技术两种核心运行机制29 2.7 上机练习30 第3章 3.1 变量32 3.1.1 什么是变量32 3.1.2 为什么需要变量32 3.1.3 变量的声明和赋值33 3.1.4 变量应用实例33 3.2 数据的分类34 3.2.1 Java中的八种基本数据类型34...

    java生成model、dao、service、controller的工具.zip

    第一阶段:Java核心基础 此阶段为入职java必备知识,必须牢牢掌握,把基础砸实是学习的根基,会让后面的内容学习变得游刃有余 2. Java设计模式 Java程序员核心技术必备,设计模式,快速通透! 3. 强化编程-数据结构...

    春季最新实战项目-智能商务系统(37.04G)

    2020-04-23-IBS-day3-代码生成器&权限 2020-04-25-IBS-day4-集成Shiro 2020-04-26-IBS-day5-登录与角色 2020-04-29-IBS-day7-导入导出 2020-04-30-IBS-day8-商品模块 2020-05-06-IBS-day9-采购单 2020-05-07-IBS-day...

    六星级 Java 高级架构

    JAVA高级进阶-实现ORM思想封装DBUtil工具类 大牛教你如何用mybatis的自动生成器来提高开发效率 京东架构师教你颠覆密码加密认知-不一样的加密 入职BAT必须技术微框架-webservice的wsdl, 深入学习springboot,轻松...

    高分毕业设计-基于Vue+Vant+SSM实现的图书管理系统可升级Springboot+源代码+文档说明+sql文件

    基于Vue图书管理app技术要点: 1 此系统web端接口采用java语言和ssm框架实现,可以升级Springboot 2 客户端和服务器通信采用axios组件,格式采用封装好的json数据格式 3 实现了图书的添加,修改,删除以及更加关键词...

Global site tag (gtag.js) - Google Analytics