zoukankan      html  css  js  c++  java
  • 一个最简单的javaagent demo实例

    JavaAgent 是JDK 1.5 以后引入的,也可以叫做Java代理。

    JavaAgent 是运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。

    那么如何实现一个 JavaAgent 呢?很简单,只需要增加 premain 方法即可,后续可以在此基础上实现注入拦截,AOP等。

    package com.xifj.agent.demo;
    import java.lang.instrument.Instrumentation;

    /**
    * Created by uc on 2018/4/18.
    */
    public class agentDemo {
    /**
    * 该方法在main方法之前运行,与main方法运行在同一个JVM中
    *
    * @param agentArgs
    * @param inst
    * @author xifeijian
    * @create 2018年4月18日
    */
    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
    * @author xifeijian
    * @create 2018年4月18日
    */
    public static void premain(String agentArgs) {
    System.out.println("=========premain方法执行2========");
    System.out.println(agentArgs);
    }
    }
    在这个 premain 函数中,开发者可以进行对类的各种操作。
    1、agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入。与 main 函数不同的是,这个参数是一个字符串而不是一个字符串数组,如果程序参数有多个,程序将自行解析这个字符串。

    2、Inst 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入。java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,也是这个包的核心部分,集中了其中几乎所有的功能方法,例如类定义的转换和操作等等。

    写完这个类后,我们还需要做一步配置工作,在 src 目录下生成 META-INF/MANIFEST.MF 文件。

     

     

    然后编辑META-INF/MANIFEST.MF,内容按如下定义:

    要特别注意,最后一行是空行,还有就是Premain-Class冒号后面有个空格,例如:

    Manifest-Version: 1.0
    Premain-Class: com.xifj.agent.demo.agentDemo

    然后我们打包代码为 javaagent.jar(Build-Artifact)


    接着我们在创建一个带有main方法的主程序工程,截图如下: 


    工程代码已完成,运行前配置VM参数:

    -javaagent:D:workspacejavaagentoutartifactsjavaagent_jarjavaagent.jar=Hello -javaagent:D:workspacejavaagentoutartifactsjavaagent_jarjavaagent.jar=World

     

    运行agentTest程序,得到以下结果:

     

    也可以将agentTest打成jar包通过java命令行执行,我们通过 -javaagent 参数来指定我们的Java代理包,值得一说的是 -javaagent 这个参数的个数是不限的,如果指定了多个,则会按指定的先后执行,执行完各个 agent 后,才会执行主程序的 main 方法。命令如下:

    java -javaagent:D:workspacejavaagentoutartifactsjavaagent_jarjavaagent.jar=hello1 -javaagent:D:workspacejavaagentoutartifactsjavaagent_jarjavaagent.jar=hello2 -jar D:workspacemyTestoutartifactsmyTest_jarmyTest.jar
    执行结果和上图是完全一致的。

    特别提醒:如果你把 -javaagent 放在 -jar 后面,则不会生效。也就是说,放在主程序后面的 agent 是无效的。

    特别注意:

    1. META-INF/MANIFEST.MF 文件,记得要加上Main-class

    Manifest-Version: 1.0
    Premain-Class: AgentDemo
    Main-Class: Main

    2. 运行亲自实践如下:



    /**
    直接命令执行
    java -javaagent:G:javacodeideaWorkSpaceMyagentoutartifactsMyagent_jarMyagent.jar=hello1 -jar Myagent.jar

    配置到启动参数:
    多个agent
    -javaagent:G:javacodeideaWorkSpaceMyagentoutartifactsMyagent_jarMyagent.jar=Hello -javaagent:G:javacodeideaWorkSpaceMyagentoutartifactsMyagent_jarMyagent.jar=World
    单个agent
    -javaagent:G:javacodeideaWorkSpaceMyagentoutartifactsMyagent_jarMyagent.jar=hello1
    **/
  • 相关阅读:
    spring boot 整合elasticsearch
    elasticsearch 高级查询
    elasticsearch 基本操作
    day9--回顾
    day9--多线程与多进程
    day9--paramiko模块
    day10--异步IO数据库队列缓存
    数据库连接池
    数据库事务的四大特性以及事务的隔离级别
    使用JDBC进行数据库的事务操作(2)
  • 原文地址:https://www.cnblogs.com/sea520/p/13186880.html
Copyright © 2011-2022 走看看