网站首页 > 精选教程 正文
上节说了javaagent和javassist,其实javassist也是基于ASM实现的。一般人不懂得JVM指令的话,根本ASM搞不起来,也用到了访问者的设计模式,看起来跟咱们写代码不是一个套路,学习成本比较高,所以有了javassist。
源码:https://github.com/limingios/netFuture/tree/master/源码/『互联网架构』插桩处理埋点(113)/
(一)插桩
- 修改上节源码,进行插桩
IdigAgentTest
package com.idig8; import com.idig8.agent.test.UserServiceImpl; import java.lang.instrument.Instrumentation; public class IdigAgentTest { public static void main(String[] args) { System.out.println("hello world idig8!"); UserServiceImpl userService = new UserServiceImpl(); userService.hello(); } }
UserServiceImpl 增加hello方法,打印方法里面的内容
package com.idig8.agent.test; public class UserServiceImpl { public UserServiceImpl(){ System.out.println("hello world!"); } public void hello(){ String p1 ="100"; System.out.print("p1 = "+p1); } }
IdigAgent 增加插桩的方法
package com.idig8.agent.test; import javassist.*; import java.io.IOException; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; import java.security.ProtectionDomain; public class IdigAgent { public static void premain(String args, Instrumentation instrumentation) { System.out.println("premain:" + args); instrumentation.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (!"com/idig8/agent/test/UserServiceImpl".equals(className)) { return null; } // javassist 工具 改造 try { ClassPool pool = new ClassPool(); pool.insertClassPath(new LoaderClassPath(loader)); CtClass ctclass = pool.get("com.idig8.agent.test.UserServiceImpl"); CtMethod method = ctclass.getDeclaredMethod("hello"); method.insertBefore(" System.out.println(System.currentTimeMillis());"); // method.insertBefore("long begin = System.currentTimeMillis();" // +" System.out.println(begin);"); // // method.insertAfter(" long end = System.currentTimeMillis();\n" + // " System.out.println(end - begin);"); return ctclass.toBytecode(); } catch (NotFoundException e) { e.printStackTrace(); } catch (CannotCompileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } }); } }
pom中添加javassist的jar包
<dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.18.1-GA</version> </dependency>
- 代码的执行流程
IdigAgentTest执行这个方法
IdigAgent ->IdigAgentTest->UserServiceImpl的类->UserServiceImpl被插桩启动开始的hello-> 打印hello方法体
premain:abc //IdigAgent hello world idig8! //IdigAgentTest hello world! //UserServiceImpl的类 1562479947074 //UserServiceImpl被插桩启动开始的hello p1 = 100 //打印hello方法体
- 注意代码
加入insertBefore中的bgin 和 insertAfter 的 end 通过end-begin 但是后台报错了
javassist.CannotCompileException: [source error] no such field: begin
为什么呢,因为插桩的时候都是以代码快的形式,局部变量。
在实际开发中不用修改原有的方法,而是会新写一个方法,在新方法进行出来,调用要插桩的方法。新方法的参数和要插桩的保持一致,包括注解,参数。其实有点类似动态代理。
public void hello$agent() { { long begin = System.currentTimeMillis(); try{ hello(); }finally { long end = System.currentTimeMillis(); System.out.println(end - begin); } } }
看到这里,点了关注吧!
- 上一篇: 高性能、无侵入的 Java 性能监控神器
- 下一篇: java监控工具(1) java视频监控
猜你喜欢
- 2024-11-07 JMX带你透视Java应用,实现应用程序的动态实时监控
- 2024-11-07 java应用监控和分析思路 java监控gc
- 2024-11-07 巧用JAVA监控工具2——jvisualvm java jvm 监控
- 2024-11-07 老技术新谈,Java应用监控利器JMX(1)
- 2024-11-07 Javaagent 使用 - 探针 jsp探针
- 2024-11-07 详解docker容器的资源监控方案 docker容器资源限制
- 2024-11-07 性能诊断利器 JProfiler 快速入门和最佳实践
- 2024-11-07 java监控工具(1) java视频监控
- 2024-11-07 高性能、无侵入的 Java 性能监控神器
- 2024-11-07 JAVA JVM常用监控工具 jvm常用的监控和调试工具
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)