Java ASM 与运行时字节码织入

背景 BTrace、Arthas、Spring LTW、部分 AOP 框架都会在不改变业务源码的前提下改写字节码。底层常依赖 ASM(或其它字节码库)配合 JVM 的 java.lang.instrument API。 本文说明 ASM 做什么、运行时织入怎么走,以及与 Attach API / Agent 的关系。BTrace 的 attach 与脚本下发见 BTrace。概念总图见 Java 领域知识关系图。ClassLoader 可见性见 java classloader。 JLS 与 java.lang.instrument 分别指什么 JLS(Java Language Specification):Java 语言规范,定义语法、类型、可见性等;不规定 Agent 怎么 attach。 java.lang.instrument:JDK 里的标准 API 包,定义 Instrumentation、ClassFileTransformer,以及 Agent 入口约定(premain / agentmain 的方法签名、manifest 的 Premain-Class / Agent-Class)。 日常说「走 instrument 机制」= 用这套 API + JVM 内置实现,在类加载或 retransform 时回调你的 transformer。 Agent 框架定义了什么、解决什么问题 Agent 不是一个限制能力的沙箱,而是一套标准钩子 + 能力接口: 约定 / 能力 作用 manifest Agent-Class / Premain-Class 告诉 JVM 加载 agent 后调用哪个类的哪个入口 agentmain / premain + Instrumentation 在 JVM 启动后或 attach 后执行你的初始化逻辑 ClassFileTransformer 在类字节码进入 JVM 前(或 retransform 时)允许你替换字节码 Attach API loadAgent 运行中的 JVM 也能挂上 agent 要解决的问题:在不重启、不改磁盘上已部署 jar 的前提下,对已在内存中的类做字节码级增强(监控、诊断、部分场景下的热修复)。 ...

Created 15156-12-15 · Updated 30306-06-30 · 3 min · 580 words · -