Java 探针的原理
Java 探针的原理其实核心就四个字:
字节码增强
一、Java 探针的核心机制
Java 探针一般是通过 Java Agent 技术实现的,依赖于 JVM 提供的 Instrumentation
接口。
1. Java Agent
- JVM 启动时,可以通过
-javaagent:xxx.jar
加载一个探针 Jar 包。 - 这个 Jar 包里需要有一个入口类,并实现
premain(String args, Instrumentation inst)
方法。 - JVM 启动时会先调用
premain
,然后再运行你的应用main
方法。
2. Instrumentation
Instrumentation
提供了操作 类加载 的能力。- 可以注册
ClassFileTransformer
,在类被加载进 JVM 时,修改它的字节码。 - 借助 ASM、Javassist 等字节码工具,就能在目标类的方法前后插入代码。
3. 探针的运行逻辑
- JVM 启动时加载探针 Jar。
- 探针注册一个 Transformer。
- 当某个类加载时,探针修改它的字节码(比如在方法入口/出口插入埋点)。
- 应用运行时,探针代码也随之运行,实现监控/拦截/增强。
二、Java 探针常见应用
-
性能监控 (APM)
- 拦截 HTTP 请求方法,记录调用链。
- 拦截 JDBC,记录 SQL 和执行时间。
- 采集 JVM 指标(GC、内存、线程)。
-
安全防护 (RASP)
- 在 Servlet 的
doFilter
拦截请求,检测 SQL 注入/XSS。 - 在
FileInputStream
、Socket
等 API 上插入检测逻辑。
- 在 Servlet 的
-
诊断工具
- Arthas、BTrace 这些工具就是探针。
- 在运行时动态 attach 探针,修改类行为,不用重启应用。
三、简单示例:打印方法执行时间的探针
Agent.java
import java.lang.instrument.Instrumentation;public class Agent {public static void premain(String args, Instrumentation inst) {System.out.println("Java Agent Loaded!");inst.addTransformer(new MyTransformer());}
}
MyTransformer.java
(用 Javassist 修改字节码)
import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;
import javassist.*;public class MyTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className,Class<?> classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer) {if ("com/example/DemoService".equals(className)) {try {ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.get("com.example.DemoService");CtMethod method = ctClass.getDeclaredMethod("process");method.addLocalVariable("start", CtClass.longType);method.insertBefore("start = System.currentTimeMillis();");method.insertAfter("System.out.println(\"耗时: \" + (System.currentTimeMillis()-start) + \"ms\");");return ctClass.toBytecode();} catch (Exception e) {e.printStackTrace();}}return classfileBuffer;}
}
运行时:
java -javaagent:my-agent.jar -jar app.jar
这样 DemoService.process()
方法就会自动打印耗时。
四、总结
-
Java 探针原理 = JVM 的 Instrumentation API + 字节码增强技术。
-
关键点:
- 通过
-javaagent
在 JVM 启动时加载。 - 修改类字节码,在方法前后插入探针逻辑。
- 适合做性能监控、安全防护、诊断。
- 通过