“免费激活”!手把手教你写一个Java Agent

前言

相信很多人都“免费激活”过 IDEA吧,在IDEA 的vmoptions配置里,加行配置就行:
“免费激活”!手把手教你写一个Java Agent_第1张图片
或者是这样“拖到IDEA窗口中”的形式:
“免费激活”!手把手教你写一个Java Agent_第2张图片
“免费激活”!手把手教你写一个Java Agent_第3张图片
再或者用过一些APM工具,在JVM启动脚本上增加了-javaagent:/path/to/apm-agent.jar,就可以自动进行追踪。再或者用过Arthas之类的JVM诊断工具,这些工具都是通过Java Agent的技术去实现的。

比如上面说的“免费激活”,其实就是在运行时期修改了验证license的相关代码。JAVA 里 Agent 这么强大的功能,你难道不打算自己亲自写一个试试吗?

基础知识

Java Agent 算是JVM的一个插件,以一个Jar包的形式存在。可以做到在运行时期,修改你的字节码文件,从而达到增强、修改等效果,通过 JVM 提供的 Instrumentation API来实现。

第一个 Java Agent

一个Java Agent,由以下几个组件构成:
“免费激活”!手把手教你写一个Java Agent_第4张图片

  • Agent Class - Agent的功能类
  • Packaging - 在MANIFEST.MF文件中定义Agent Class的位置和方式
  • “装载点”,比如-javaagent:[=arguments],指定加载的agent.jar文件

废话不多说,下面正式开始编写这个Agent

1. 创建Agent Class

首先要创建一个Agent Class,这个Class作为我们Agent插件的入口类。配置好-javaagent后,JVM在启动时会执行我们Agent Class的premain方法

import java.lang.instrument.Instrumentation;

public class Agent {
   
  public static void premain(String args, Instrumentation instrumentation){
   
    ClassLoggerTransformer transformer = new ClassLoggerTransformer();
    instrumentation.addTransformer(transformer);
  }
}

在premain方法中,除了args参数,还有一个instrumentation对象。这个是Java Agent的核心对象,通过该对象可以注册ClassFileTransformer。

**ClassFileTransformer **就是负责字节码转换的核心接口了,已注册的ClassFileTransformer可以拦截JVM中所有类的加载,并且可以获取到已加载类的字节码,来看一下这个接口的源码:

public interface ClassFileTransformer {
   
    byte[]
    transform(  ClassLoader         loader,
                String              className,//className,全类名(包括路径,"/"分割)
                Class<?>            classBeingRedefined,//类定义转换时的Class对象,初始加载时为空
                ProtectionDomain    protectionDomain,//protection...
                byte[]              classfileBuffer)//加载的Class字节码数据
        throws IllegalClassFormatException;
}

2. 定义一个Transformer<

你可能感兴趣的:(Java,JVM,spring,java,大数据,编程语言,jvm,spring)