JavaAgent学习之旅(二|动态的agentmain demo实例)
agentmain和premain方法不一样的点在于,agentmain是可以在类加载到jvm之后改变字节码的行为,premain只能在类加载到jvm之前修改字节码文件,简单来说一个是运行期改变字节码,一个是加载期改变字节码
code:
首先agent-demo,项目结构同上一篇文章的项目结构,不同的是文件内容不一样
AgentDemo:
package com.shi; import java.lang.instrument.Instrumentation; /** * @author DaTou * @Description * @Date 2020/9/21 **/ public class AgentDemo { /** * premain 静态载入的情况 * agentmain 动态载入的情况 * @param agentOps * @param instrumentation */ public static void premain(String agentOps, Instrumentation instrumentation) { System.out.println("====premain method===="); } public static void simpleDome(String agentOps,Instrumentation instrumentation){ System.out.println("do something for class"); } public static void agentmain(String agentOps,Instrumentation instrumentation){ System.out.println("====agent main method===="); } }
MANIFEST.MF
Manifest-Version: 1.0 Premain-Class: com.shi.AgentDemo Agent-Class: com.shi.AgentDemo
然后新建一个main方法吧,我新加的一个project,项目结构如下:

AgentAttachDoMain:
package com.shi;
import com.sun.tools.attach.*;
import java.io.IOException;
import java.util.List;
/**
* @author DaTou
* @Description
* @Date 2020/9/22
**/
public class AgentAttachDoMain {
public static void main(String[] args) {
//注意:VirtualMachineDescriptor这个类归属于lib/tools.jar,java8是没有把他自动加载进来的,需要在Platform settings里加入jdk的这个包
List<VirtualMachineDescriptor> virtualMachineDescriptors = VirtualMachine.list();
for (VirtualMachineDescriptor descriptor:virtualMachineDescriptors){
if (descriptor.displayName().endsWith("AgentDemoDoMain")){
try {
VirtualMachine virtualMachine = VirtualMachine.attach(descriptor.id());
virtualMachine.loadAgent("xxxx\\agent-demo-1.0-SNAPSHOT.jar");//这个就是agent-demo打完包的路径
virtualMachine.detach();
} catch (AttachNotSupportedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (AgentLoadException e) {
e.printStackTrace();
} catch (AgentInitializationException e) {
e.printStackTrace();
}
}
}
}
}

浙公网安备 33010602011771号