java agent的简单使用

1 篇文章 0 订阅
1 篇文章 0 订阅
package com.meng.apm.javaagent.simple;

import java.lang.instrument.Instrumentation;


/**
 * jdk1.5以后引入了javaAgent技术,javaAgent是运行方法之前的拦截器。
 * 我们利用javaAgent和ASM字节码技术,在JVM加载class二进制文件的时候,利用ASM动态的修改加载的class文件
 *
 * 如果你把 -javaagent 放在 -jar 后面,则不会生效。也就是说,放在主程序后面的 agent 是无效的。
 *
 *
 * 测试
 * -javaagent:E:\workspace\netty\out\artifacts\nettyagent_jar\netty.jar=Hello -javaagent:E:\workspace\netty\out\artifacts\nettyagent_jar\netty.jar=World
 */
public class TestAgent {

    /**
     * 该方法在main方法之前运行,与main方法运行在同一个JVM中
     * 并被同一个System ClassLoader装载
     * 被统一的安全策略(security policy)和上下文(context)管理
     *
     * 在这个 premain 函数中,开发者可以进行对类的各种操作。
     * 1、agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入。与 main 函数不同的是,
     * 这个参数是一个字符串而不是一个字符串数组,如果程序参数有多个,程序将自行解析这个字符串。
     * 2、Inst 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入。*
     * java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,也是这个包的核心部分,
     * 集中了其中几乎所有的功能方法,例如类定义的转换和操作等等。
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("=========premain方法执行1========");
        System.out.println(agentArgs);
    }

    /**
     * 如果不存在 premain(String agentArgs, Instrumentation inst)
     * 则会执行 premain(String agentArgs)
     * @param agentArgs
     */
    public static void premain(String agentArgs) {
        System.out.println("=========premain方法执行2========");
        System.out.println(agentArgs);
    }

}

 

打包jar

编译jar包  build artifacts

生成jar包

 

新建一个项目代码如下:

 

 

 

结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Agent是一种Java技术,它可以在程序运行时动态地修改或增强现有的Java类。Java Agent可以用于很多场景,其中之一就是实现Java应用程序的热更新。下面是一个简单Java Agent热更新的示例: 1.编写Java Agent程序,实现热更新功能。具体实现可以使用Java工具包tools.jar提供的agentmain方法,该方法可以在程序运行时动态地修改或增强现有的Java类。以下是一个简单Java Agent程序示例: ```java public class HotUpdateAgent { public static void agentmain(String agentArgs, Instrumentation inst) throws Exception { // 获取要更新的类的类名 String className = "com.example.demo.HelloWorld"; // 获取要更新的类的字节码文件 byte[] classBytes = getClassBytes(className); // 重新定义要更新的类 ClassDefinition classDefinition = new ClassDefinition(Class.forName(className), classBytes); inst.redefineClasses(classDefinition); } private static byte[] getClassBytes(String className) throws Exception { // 读取要更新的类的字节码文件 FileInputStream fis = new FileInputStream(className.replaceAll("\\.", "/") + ".class"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { bos.write(buffer, 0, len); } fis.close(); bos.close(); return bos.toByteArray(); } } ``` 2.在需要热更新的Java应用程序中,使用Java Agent实现热更新。具体实现可以使用Java命令的-javaagent参数来指定Java Agent程序,并使用HotUpdateServer类来启动Java应用程序。以下是一个简单Java应用程序示例: ```java public class HelloWorld { public static void main(String[] args) throws Exception { while (true) { System.out.println("Hello World!"); Thread.sleep(1000); } } } ``` 3.使用HotUpdateServer类来启动Java应用程序,并使用Java命令的-javaagent参数来指定Java Agent程序。以下是一个简单的HotUpdateServer类示例: ```java public class HotUpdateServer { public static void main(String[] args) throws Exception { // 获取要更新的Java应用程序的pid String pid = args[0]; // 获取要更新的类的项目目录和类名 String classPath = args[1]; // 获取执行引擎jar的路径 String enginePath = args[2]; // 启动Java应用程序 Process process = Runtime.getRuntime().exec("java -javaagent:" + enginePath + " -cp " + classPath + " HelloWorld"); // 获取Java应用程序的输入流和输出流 InputStream inputStream = process.getInputStream(); OutputStream outputStream = process.getOutputStream(); // 启动热更新线程 new Thread(() -> { while (true) { try { // 等待用户输入命令 Scanner scanner = new Scanner(System.in); String command = scanner.nextLine(); // 发送命令到Java应用程序 outputStream.write((command + "\n").getBytes()); outputStream.flush(); // 读取Java应用程序的输出 byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { System.out.write(buffer, 0, len); } } catch (Exception e) { e.printStackTrace(); } } }).start(); // 等待Java应用程序退出 process.waitFor(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值