一:什么是JavaAgent
JavaAgent顾名思义就是Java探针技术,我理解的是,通过一个JavaAgent探针类,可以在java虚拟机启动之前,或者运行的时候植入这个探针类,对jvm做一些特别的 *** 作,如动态改变字节码文件这种,要想植入,肯定是通过jvm参数来搞了
使用JavaAgent的技术的项目我目前知道的是SkyWalking,dubbo用没用我没印象了
一、创建一个自定义的anget让JavaAgent在被代理程序在JVM运行启动的时候,做一些 *** 作
1、创建一个Maven空项目不选模版直接next(也可以是纯净的Java项目注:不要选spring项目,否则打包和执行时都会报错)
2、编写代理内容
package com.jacky; import java.lang.instrument.Instrumentation; public class PreMyProgram { public static void premain(String agentOps,Instrumentation inst){ System.out.println("====premain 方法执行"); System.out.println(agentOps); } }
3、定义MANIFEST.MF(呈现文件清单,指明入口类等)
自己写好一个MANIFEST.MF
Manifest-Version: 1.0 Premain-Class: com.jacky.PreMyProgram Can-Redefine-Classes: true
然后在pom文件中指定自定义的MANIFEST.MF:
4.0.0 org.jacky java-agent-doem1.0-SNAPSHOT 8 8 org.springframework.boot spring-boot-maven-pluginorg.apache.maven.plugins maven-jar-pluginsrc/main/resources/meta-INF/MANIFEST.MF true org.apache.maven.plugins maven-surefire-plugintrue
然后就可以mvn package了,打包得到jar包
整个文件结构:
二、创建被代理程序
我们创建一个可正常运行的springboot项目,打包得到mockStrategyCenter-0.0.1-SNAPSHOT.jar的包
为了方便测试 我们把两个代理包 和被代理包都放到相同文件夹
三、执行
如何执行?我们通过 -javaagent 参数来指定我们的Java代理包,值得一说的是 -javaagent 这个参数的个数是不限的,如果指定了多个,则会按指定的先后执行,执行完各个 agent 后,才会执行主程序的 main 方法。(此处我们指定了两个)
java -javaagent:./java-agent-doem-1.0-SNAPSHOT.jar=Hello1 -javaagent:./java-agent-doem-1.0-SNAPSHOT.jar=Hello2 -jar mockStrategyCenter-0.0.1-SNAPSHOT.jar
执行结果:
特别提醒:
(1)如果你把 -javaagent 放在 -jar 后面,则不会生效。也就是说,放在主程序后面的 agent 是无效的。
至此简单的通过javaAgent去实现被代理程序在JVM运行启动插入 *** 作就实现了,后续我们可以通过结合asm字节码技术,实现对被代理程序源码编译后的字节码在jvm加载过程中的动态修改,去实现各种监控,插桩等场景
命令中的Hello1为我们传递给 premain 方法的字符串参数。
至此,我们会使用 javaagent 了,但是单单看这样运行的效果,好像没有什么实际意义嘛。
我们可以用 javaagent 做什么呢?下篇文章我们来介绍如何在项目中应用 javaagent。
最后说一下,还有一种,在main方法执行后再执行代理的方法,因为不常用,而且主程序需要配置 Agent-Class,所以不常用,如果需要自行了解下 agentmain(String agentArgs, Instrumentation inst) 方法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)