java集成agent作用,Java Agent基本简介和使用

javaagent简介

javaagent是一种能够在不影响正常编译的情况下,修改字节码。java作为一种强类型的语言,不通过编译就不能能够进行jar包的生成。而有了javaagent技术,就可以在字节码这个层面对类和方法进行修改。同时,也可以把javaagent理解成一种代码注入的方式。但是这种注入比起spring的aop更加的优美。

javaagent主要作用

可以在加载java文件之前做拦截把字节码做修改

可以在运行期将已经加载的类的字节码做变更,但是这种情况下会有很多的限制,后面会详细说

还有其他的一些小众的功能

获取所有已经被加载过的类

获取所有已经被初始化过了的类(执行过了clinit方法,是上面的一个子集)

获取某个对象的大小

将某个jar加入到bootstrapclasspath里作为高优先级被bootstrapClassloader加载

将某个jar加入到classpath里供AppClassload去加载

设置某些native方法的前缀,主要在查找native方法的时候做规则匹配

javaagent的使用

通过 -javaagent:xxx.jar=name=lisi&age=30 其中 xxx.jar 指定对应要加载的jar包的名字和路径,后面跟踪自己传入的参数即可

IDEA中传入参数可以参考下图

de6bde2e30a2

CE3544A45245B229746E496D57FF29F1.jpg

新建agent

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包路径

org.apache.maven.plugins

maven-jar-plugin

2.6

${project.name}

${project.version}

com.mergades.apm.javaagent.HelloAgent

true

org.apache.maven.plugins

maven-compiler-plugin

2.3.2

8

8

utf8

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 方法

Agentjar和普通jar的区别

运行时jar

agent

入口方法名称

Main

premain

Maninfe.MF 主要参数

Main-class

Premain-Class

启动参数

java -jar xxx.jar

-javaagent:xxx.jar

执行顺序

是否独立启动

agent 代码植入

执行方法前加入代码,执行方法后加入代码

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);// 使用全称,用于取得字节码类

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值