赞
踩
javaagent是一种能够在不影响正常编译的情况下,修改字节码。java作为一种强类型的语言,不通过编译就不能能够进行jar包的生成。而有了javaagent技术,就可以在字节码这个层面对类和方法进行修改。同时,也可以把javaagent理解成一种代码注入的方式。但是这种注入比起spring的aop更加的优美。
通过 -javaagent:xxx.jar=name=lisi&age=30 其中 xxx.jar 指定对应要加载的jar包的名字和路径,后面跟踪自己传入的参数即可
IDEA中传入参数可以参考下图
- package com.mergades.apm.javaagent;
-
- import java.lang.instrument.Instrumentation;
-
- /**
- * https://blog.csdn.net/fd2025/article/details/80280033
- */
- public class HelloAgent {
-
- public static void premain(String arg, Instrumentation instrumentation) {
- System.out.println("装载成功 方法 premain 参数:" + arg);
- }
- }
-
maven pom文件引入对应的jar包插件,指定mainfestEntries,指定自己的jar包路径
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.6</version>
- <configuration>
- <archive>
- <manifestEntries>
- <Project-name>${project.name}</Project-name>
- <Project-version>${project.version}</Project-version>
- <Premain-Class>com.mergades.apm.javaagent.HelloAgent</Premain-Class>
- </manifestEntries>
- </archive>
- <skip>true</skip>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>8</source>
- <target>8</target>
- <encoding>utf8</encoding>
- </configuration>
- </plugin>
- </plugins>
- </build>
mvn install 打包
编写单元测试
- package com.mergades.apm.javaagent;
-
-
- public class HelloAgentTest {
- public static void main(String[] args) {
- System.err.println("TestHelloAgent main 方法");
- }
- }
单元测试run config引入自己的agent jar,直接运行,获取agent植入的输出结果。
- 装载成功 方法 premain 参数:name=lisi&age=30
- TestHelloAgent main 方法
运行时jar | agent | |
---|---|---|
入口方法名称 | Main | premain |
Maninfe.MF 主要参数 | Main-class | Premain-Class |
启动参数 | java -jar xxx.jar | -javaagent:xxx.jar |
执行顺序 | 先 | |
是否独立启动 | 是 | 否 |
执行方法前加入代码,执行方法后加入代码
- package com.mergades.apm.classpool;
-
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtMethod;
-
- import java.lang.instrument.ClassFileTransformer;
- import java.lang.instrument.IllegalClassFormatException;
- import java.security.ProtectionDomain;
-
- public class FirstAgent implements ClassFileTransformer {
-
- public final String injectedClassName = "com.mergades.apm.javaagent.HelloAgentTest";
- public final String methodName = "hello";
-
- @Override
- public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
- className = className.replace("/", ".");
- if (className.equals(injectedClassName)) {
- CtClass ctclass;
- Long start = System.nanoTime();
- try {
- ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类<使用javassist>
- CtMethod ctmethod = ctclass.getDeclaredMethod(methodName);// 得到这方法实例
- ctmethod.insertBefore("System.out.println(11111111);");
- return ctclass.toBytecode();
- } catch (Exception e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
- } finally {
- System.out.println("className took:" + (System.nanoTime() - start));
- }
- }
- return null;
-
- }
- }
-
- package com.mergades.apm.javaagent;
-
- import com.mergades.apm.classpool.FirstAgent;
-
- import java.lang.instrument.Instrumentation;
-
- /**
- * https://blog.csdn.net/fd2025/article/details/80280033
- */
- public class HelloAgent {
-
- public static void premain(String arg, Instrumentation instrumentation) {
- System.out.println("premain 装载成功 方法 premain 参数:" + arg);
-
- // 添加Transformer
- instrumentation.addTransformer(new FirstAgent());
- }
- }
-
单元测试
- package com.mergades.apm.javaagent;
-
-
- public class HelloAgentTest {
- public static void main(String[] args) {
- System.err.println("TestHelloAgent main 方法");
-
- hello();
- }
-
- public static void hello() {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("HelloAgentTest hello() output");
- }
-
- }
输出结果
- premain 装载成功 方法 premain 参数:name=lisi&age=30
- className tooks:201016907
- TestHelloAgent main 方法
- 11111111
- HelloAgentTest hello() output
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。