小王是一个刚来不久的妹子 , 啊呸 , 是一个刚来不久的程序媛 , 经常垂头丧气的~让我很是不解 , 终于有一天我怕小王哪天想不开离职了岂不是会增加我的工作量(部门为数不多的妹子 - 1)?于是乎 , 我主动找小王进行了谈心找到了问题所在 , 原来是小王编程经验不足 , 不知道如何巧妙的进行日志打印 , 那么因果关系就总结出来了:经验不足导致编码经常出错 , 编码出错由于日志未打印导致排查困难 , 排查困难导致开发抑郁 。查到问题的原因 , 那么进行对症下药即可~
其实以上问题我相信很多小伙伴都遇到过 , 开发过程中未出现的错误在上线后就频频出现 , 那么只能不断的进行添加日志打印然后再打包上传进行问题跟踪 , 一天的时间绝大部分都浪费在了打包上传的上面 。那么能不能直接进行bug跟踪 , 然后查看到问题出错的所在?这种需求不亚于给奔跑中的汽车更换轮胎 , 匪夷所思却又无可奈何~其实有开发经验的小伙伴已经想出来一个中间件 , 那就是 Arthas!但是这篇文章不是介绍如何使用 Archas , 而是我们自己能不能实现这种动态调试的技能?那么就进入我们今天的整体 --- JAVA Agent 技术
Java Instrument这个玩意并不是什么 Java 的新特性 , 早在 JDK 1.5 的时候就诞生了 , 位于
java.lang.instrument.Instrumentation 中 , 它的作用就是用来在运行的时候重新加载某个类的 calss 文件的 api 。
这种类的实现方式其实是一种 Java Agent 技术 , 我们这里可以顺带了解一下什么是 Java Agent 。
一、Java Agent代理这个词对于我们开发人员来说并不默认 , 我们经常用到的 AOP 面向切面编程用到的就是代理方式 。它可以动态切入某个面 , 进行代码增强。这种不用重复补充轮子的方式大大增加了我们开发效率 , 那么这里捕获到了一个关键词 动态 。那么 Java Agent 如何实现?那就可以说到 JVMTI(JVM Tool Interface) , 这是Java 虚拟机对外提供的 Native 编程接口 , 通过它我们可以获取运行时JVM的诸多信息 , 而 Agent 是一个运行在目标 JVM 的特定程序 , 它可以从目标 JVM 获取数据 , 然后将数据传递给外部进程 , 然后外部进程可以根据获取到的数据进行动态Enhance 。
文章插图
那么 Java Agent 什么时候能够加载?
- 目标 JVM 启动时
- 目标 JVM 运行时
而 Java Agent看上去这么高大上 , 我们要如何编写?当然在 JDK 1.5 之前 , 实现起来是具有困难性的 , 我们需要编写 Native 代码来实现 , 那么 JDK 1.5 之后我们就可以利用上面说到的 Java Instrument 来实现了!
首先我们先了解一下 Instrumentation 这个接口 , 其中有几个方法:
- addTransformer(ClassFileTransformer transformer, boolean canRetransform)
- retransformClasses(Class<?>... classes)
- redefineClasses(ClassDefinition... definitions)
- getObjectSize(Object objectToSize)
- AppendToBootstrapClassLoaderSearch(JarFile jarfile)
- getAllLoadedClasses()
redefineClasses 和 retransformClasses 补充说明
推荐阅读
- 阿里架构师整理的 Netty 学习笔记之:Java NIO 网络编程
- Javascript的New、Apply、Bind、Call知多少
- 莳萝子在香肠中的用量,莳萝在烹调中的作用及用法
- 什么是Java中的反应性流?
- 莳萝对皮肤的作用,莳萝在烹调中的作用及用法
- 快速了解JavaScript的DOM模型
- Java 文件操作必知概念
- java开发框架之SSM整合框架
- 明日草的功效与作用和用法,明日叶的功效
- 普洱茶花式饮用法,水煎普洱茶的功效