| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> Instrumentation类方法简单介绍 -> 正文阅读 |
|
[人工智能]Instrumentation类方法简单介绍 |
文章目录
前言Instrumentation主要是提供Java代码增强功能。例如为了提供收集数据的功能,可以通过字节码增强技术,对类的方法进行增强。由于代码是添加的,所以他不会修改原来的状态。通过这个API,我们可以开发各种工具,例如监控的客户端,profiles,代码覆盖率分析工具以及事件的日志埋点工具。 提示:以下是本篇文章介绍其中的方法 一、Instrumentation类1.addTransformer(ClassFileTransformer transformer, boolean canRetransform)代码如下(示例):
函数的作用是注册一段代码增强逻辑,它能对所有已定义的类生效(除了通过依赖的transformer进行定义的类)。 2.addTransformer(ClassFileTransformer transformer)代码如下(示例):
等同于addTranformer(transformer,false); 3.removeTransformer(ClassFileTransformer transformer)代码如下(示例):
移除已注册的transformer。未来被定义的类将不会被应用这个transformer。由于类加载的多线程语义性,可能被移除的transformer还会依然生效,所以业务方在编写的时候要处理好,做好防御性编程。 4.isRetransformClassesSupported()代码如下(示例):
返回当前的JVM配置是否支持类的reTransform。这个取决于你的javaagent里manifest的配置项的Can-Retransform-Classes配置 5.retransformClasses(Class… classes) throws UnmodifiableClassException代码如下(示例):
函数的用途是对传入的classes执行transform,一般用于agentmain的方式。因为agentmain的方式是在class已经被加载完了之后attch到jvm上的,这个时候只有通过这种方式来修改原来的类的行为。 所以在add的时候,canTransform设置为false的将会被忽略,只有设置为true的才会被执行。如果你的jvm的Can-Retransform-Classes被设置为false,会抛出异常。同时如果你的类有问题,可能会抛出ClassFormatError,NoClassDefFoundError,ClassCircularityError,LinkageError异常,如果传入的是null,会报NullPointerException 6.isRedefineClassesSupported()代码如下(示例):
同isRetransformClassesSupported,在manifest里配置的 7.redefineClasses(ClassDefinition… definitions) throws ClassNotFoundException, UnmodifiableClassException代码如下(示例):
和retransformClasses非常的相似。 8.isModifiableClass(Class theClass)代码如下(示例):
这个类是否能够被transform,如果可以则返回true 9.getAllLoadedClasses()代码如下(示例):
获取所有被JVM加载的类,这个是诊断的好帮手 10.getInitiatedClasses(ClassLoader loader)代码如下(示例):
获取所有被指定的classloader加载的类,如果传入null则返回由BootstrapClassl返回的类 11.getObjectSize(Object objectToSize)代码如下(示例):
获取一个对象消耗的空间大小 12.appendToBootstrapClassLoaderSearch(JarFile jarfile)代码如下(示例):
将指定的jar包加载给BootstrapClassLoader,可以被执行多次从而加载多个jar包。查找类的时候会先去BootStrapLoader里去找,如果找不到就到这个jar包里面去找。 需要小心处理的是,包名不要重复。例如,在ClassLoader L里加载了一个类C,他有一个私有类是C$1,如果你的jar包里正好也有个类C$1,他会先去BootstrapClassLoader里去找,发现找到了,然后去load,接着发现没有权限,就会直接报出IllegalAccessError错误。 13.appendToSystemClassLoaderSearch(JarFile jarfile)代码如下(示例):
特性和appendToBootstrapClassLoader类似,不过区别是这个是用于SystemClassLoader的类的查找的(回忆一下双亲委派机制)。 14.isNativeMethodPrefixSupported()代码如下(示例):
是否设置了本地方法的拦截,由manifest设置的。Can-Set-Native-Method-Prefix属性,具体set native method prefix的用途参考nativeMethodPrefix() 15.setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)代码如下(示例):
对本地方法进行代码增强。但是由于本地方法是没有字节码的,所以他的办法是重新定义一个同名的函数(原来native method)的名称,然后将原来的本地方法使用prefix进行重命名。 举例,以前有一个本地方法 native boolean foo(String x),他的做法是先将native的方法重命名,例如改成
为了防止重复,所以你的prefix最好考虑到方法重复的情况。 正常情况下,按照上面顺序执行,但是如果有问题的时候他的执行顺序分别是 method(foo) -> nativeImplementation(foo) 二、ClassFileTransformer类用来让用户来实现代码增强逻辑的接口。他只有一个方法,方法的参数是原来的类的字节码以及这个类的classloader对象,返回值则是被增强之后的类的字节码。所以你的代码是通过已有的类信息,植入代码之后,形成新的代码(类的字节码)。 1.transform代码如下(示例):
这里的来源有两个,分别是Instrumentation的两个addInstrumentation()方法。
例如原始方法是foo(String x), 然后在类加载的时候进行了一些增强,插入了一段代码,那么在下次retransformClasses执行,这个方法被调用的时候,增加的字节码是在上一次的基础上进行的。换句话说,classfileBuffer永远都是最后增强执行完成之后的版本。 关于异常和返回值。如果返回值是null,代表这次调用什么都没做,没有任何增强代码加入。他的效果和抛出异常是一样的,如果在执行这个函数的过程中抛出了异常,则代表本次调用什么都不做,和返回null值的效果是一样的。 总结本文仅仅简单介绍了Instrumentation类的方法,具体Instrumentation的使用还需要结合Javassit开源的分析、编辑和创建Java字节码的类库,后续会继续介绍 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/17 22:22:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |