(二)Java1.8核心包rt.jar——java.lang.instrument

1、ClassFileTransformer

/**
* 参数:
* loader - 正在加载类的类加载器
* className - 正在加载的类的名称
* classBeingRedefined -重定义的类
* protectionDomain-要定义或重定义的类的保护域
* classfileBuffer-类文件格式的输入字节缓冲区(不得修改)
*/
1 public interface ClassFileTransformer
2 {
3     
4     byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
5         ProtectionDomain protectionDomain, byte[] classfileBuffer)
6         throws IllegalClassFormatException;
7 }

2、Instrumentation

 1  public interface Instrumentation {2  3     //添加ClassFileTransformer4     void addTransformer(ClassFileTransformer transformer, boolean canRetransform);5     6     //添加ClassFileTransformer7     void addTransformer(ClassFileTransformer transformer);8     9     //移除ClassFileTransformer
10     boolean removeTransformer(ClassFileTransformer transformer);
11     
12     //是否可以被重新定义
13     boolean isRetransformClassesSupported();
14     
15     //重新定义Class文件
16     void redefineClasses(ClassDefinition... definitions)
17         throws ClassNotFoundException, UnmodifiableClassException;
18     
19     //是否可以修改Class文件
20     boolean isModifiableClass(Class<?> theClass);
21     
22     //获取所有加载的Class
23     @SuppressWarnings("rawtypes")
24     Class[] getAllLoadedClasses();
25     
26     //获取指定类加载器已经初始化的类
27     @SuppressWarnings("rawtypes")
28     Class[] getInitiatedClasses(ClassLoader loader);
29     
30     //获取某个对象的大小
31     long getObjectSize(Object objectToSize);
32     
33     //添加指定jar包到启动类加载器检索路径
34     void appendToBootstrapClassLoaderSearch(JarFile jarfile);
35     
36     //添加指定jar包到系统类加载检索路径
37     void appendToSystemClassLoaderSearch(JarFile jarfile);
38     
39     //本地方法是否支持前缀
40     boolean isNativeMethodPrefixSupported();
41     
42     //设置本地方法前缀,一般用于按前缀做匹配操作
43     void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix);
44 }

3、 java.lang.instrument简介

  • Java5之后,增加了一个包java.lang.instrument,这个包的东西很少,两个接口,ClassFileTransformer和Instrumentation,一个类ClassDefinition,还有两个Exception:IllegalClassFormatException和UnmodifiableClassException;

  • Instrument的最大作用,就是类定义的动态改变和操作。在 Java SE 5 及其后续版本当中,开发者可以在一个普通 Java 程序(带有 main 函数的 Java 类)运行时,通过 -javaagent参数指定一个特定的 jar 文件(包含 Instrumentation 代理)来启动 Instrumentation 的代理程序。

  • 一个代理就是部署一个Jar文件。Jar文件的manifest文件(每个jar包根目录下有个META-INF文件夹,此文件夹下的MANIFEST.MF文件就是这里的manifest文件)需要指定这个代理的类,指定之后,这个类将被加载以启动代理。因为支持命令行接口,所以一个代理可以通过在命令行中指定一个选项来移动。具体的实现也可能支持在虚拟机启动之后的某个时间开启代理。例如,一个具体的实现可能提供一个机制,使一个工具附加到一个运行的应用中,然后,初始化这个工具的代理,加载到正在运行的应用中。关于类的加载如何被初始化的细节,依赖于具体的实现。

  • 在用命令行接口的实现中,一个代理可以通过增加下面的Option到命令行中启动:

-javaagent:jarpath[=options]jarpath是代理jar文件的路径。option是代理的选项。上边的命令可以在同一个命令行中使用多次,因此,可以创建多个代理。多个代理可以使用同一jarpath。一个代理Jar文件必须符合Jar文件规范。
  • 一个代理jar文件的manifest必须包含Premain-Class属性。这个属性的值是代理类的名字。代理类必须实现一个public static的premain 方法,与应用程序中的main方法作为程序入口的原理类似。JVM初始化之后,每一个premain方法将被以代理被指定时的顺序调用,然后应用程序真正的main方法将被调用。每一个premain方法必须以启动的顺序返回结果。(premain=pre-main)

JVM首先尝试调用代理类中下面的方法:public static void premain(String agentArgs, Instrumentation inst);如果代理类没有实现这个方法,jvm将尝试调用public static void premain(String agentArgs);
  • 一个代理具体的实现可能提供一个在JVM启动之后启动的机制。关于代理被初始化的细节是具体实现特定的,但是通常应用程序已经启动,应用程序的main方法已经被调用。在代理的实现支持在JVM启动之后启动的情况下,需要遵循下面的规则:
  1.  代理的Jar文件中的manifest文件必须包含Agent-Class属性。这个属性的值是代理类的名字。
    
  2.  代理类必须实现一个public static agentmain方法
    
  3.  系统类加载器( ClassLoader.getSystemClassLoader)必须支持增加一个代理Jar文件到系统类路径。
    

代理的Jar文件被追加到系统类路径中。这个类加载器是通常用来加载包含应用程序main方法的类的类加载器。代理类被加载之后,JVM尝试调用agentmain方法。


JVM首先尝试调用代理类中的下面这个方法:public static void agentmain(String agentArgs, Instrumentation inst);如果代理类中没有实现这个方法,然后JVM尝试调用:public static void agentmain(String agentArgs);

这个代理类可能也有一个premain方法,当代理在命令行选项中启动时使用;当这个代理类在JVM启动之后启动时,premain方法不会被调用。

  • manifest属性在一个代理的jar文件中被定义:
Premain-Class当一个代理在JVM启动时被指定时,这个属性指定代理使用的类。也就是,这个类包含premain方法。当一个代理在JVM启动时被指定时,这个属性是必须的。如果没有配置这个属性,JVM将会abort。注意:这是一个类的名字,不是一个文件名活路径。Agent-Class如果一个代理的实现支持在JVM启动之后的某个时间启动,这个属性指定一个代理类。也就是说,这个类要包含agentmain方法。这个属性是必须的,如果不配置的话,代理将不会被启动。注意:这是一个类的名字,不是一个文件名字,也不是文件路径。Boot-Class-Path这个代理的实现中用到的第三方jar包都放到这里边。Can-Redefine-ClassesBoolean(true或false)。Agent是否可以重定义类。可选的,默认是false。Can-Retransform-ClassesBoolean(true或false)。Agent是否可以将类变回原形。可选的,默认是false。Can-Set-Native-Method-PrefixBoolean(true或false)。Agent是否可以设置本地方法的前缀。可选的,默认是false。
  • 一个代理Jar文件中的manifest文件可能同时包含Premain-Class和Agent-Class属性。当代理在命令行中用-javaagent选项被启动,使用Premain-Class属性指定的代理类的名字,然后Agent-Class属性的配置被忽略。相似地,如果代理在JVM启动之后的某个时间启动,使用Agent-Class属性指定的类的名字,Premain-Class属性被忽略。

4、 示例

(1) 启动时加载

Agent类

 public class MyAgent {public static void premain(String args,Instrumentation inst){System.out.println("premain方法会在main方法之前执行......");inst.addTransformer(new MyTransformClass());}}

ClassFileTransformer类

 public class MyTransformClass implements ClassFileTransformer{@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,ProtectionDomain protectionDomain, byte[] classfileBuffer)throws IllegalClassFormatException{// 编译后的字符流数组byte[] newClassFileBuffer = new byte[classfileBuffer.length];// 重定义指定类String transClassName = "com.App";if (className.equals(transClassName)){System.out.println("监控到目标类");// 对byte[]重新编译可以使用第三方工具如javassistnewClassFileBuffer = classfileBuffer;}return newClassFileBuffer;}}

MANIFEST.MF文件

Manifest-Version: 1.0
Premain-Class:com.test.MyAgent 
Boot-Class-Path: javassist.jar

打jar包

jar cvfm MyAgent.jar MANIFEST.MF  javassist.jar  com将MANIFEST.MF文件,javassist.jar,com文件夹下的类打成jar包

编写测试类

public class App {public static void main(String[] args) {System.out.println("HelloWorld!!");}
}

执行测试

java   -javaagent:MyAgent.jar   App

(2)运行时加载

Agent类

 public class MyAgent {public static void agentmain(String args, Instrumentation inst) {Class[] classes = inst.getAllLoadedClasses();for(Class cls :classes){System.out.println(cls.getName());}}}

MANIFEST.MF文件

Manifest-Version: 1.0
Agent-Class::com.test.MyAgent 
Boot-Class-Path: javassist.jar

打jar包

jar cvfm MyAgent.jar MANIFEST.MF  javassist.jar  com将MANIFEST.MF文件,javassist.jar,com文件夹下的类打成jar包

编写测试类,用jps命令可以方便的查看进程的ID,名字是应用程序main方法所在的类的名字。

public class TargetVM {public static void main(String[] args) throws InterruptedException {while (true) {Thread.sleep(1000);}}
}

执行测试

public class Test {public static void main(String[] args) throws AttachNotSupportedException,IOException, AgentLoadException, AgentInitializationException {VirtualMachine vm = VirtualMachine.attach(args[0]);vm.loadAgent("MyAgent.jar");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/57316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MP9928模块分析

MP9928 是一款高性能的同步降压 DC/DC 转换器控制器 IC&#xff0c;具有宽输入范围。以下是其操作和关键特性的总结&#xff1a; 概述 电流模式控制&#xff1a;MP9928 使用电流模式、可编程开关频率控制架构&#xff0c;通过外部 N 沟道 MOSFET 开关来调节输出电压。 反馈和…

Golang | Leetcode Golang题解之第500题键盘行

题目&#xff1a; 题解&#xff1a; func findWords(words []string) (ans []string) {const rowIdx "12210111011122000010020202" next:for _, word : range words {idx : rowIdx[unicode.ToLower(rune(word[0]))-a]for _, ch : range word[1:] {if rowIdx[unico…

【uni-app学习-2】

一、跳转 方法&#xff1a;在methods中去定义方法&#xff1a; 上述为直接跳转&#xff0c;但是当你要跳转页面是由多个可切换页面组成比如&#xff1a; 这个页面其实是由两个页面组成&#xff0c;一个主页&#xff0c;一个我的&#xff0c;两个页面 路由配置需要用到toob…

房屋租赁网站毕业设计基于SpringBootSSM框架的计算机毕业设计

计算机毕业设计/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序 目录 一、项目背景与目的‌ ‌二、系统需求分析‌ 2.1功能需求 2.2 技术需求 2.3 可执行性 ‌三、系统设计与实现‌ ‌3.1系统架构设计‌&#xff1a; ‌3.2功能模块开发‌&#xff1a; ‌3.3…

golang生成并分析cpu prof文件

1. 定义一个接口&#xff0c;请求接口时&#xff0c;生成cpu.prof文件 在主协程中新启一个协程&#xff0c;当请求接口时&#xff0c;生成一个60秒的cpu.prof文件 go func() {http.HandleFunc("/prof", startProfileHandler)http.ListenAndServe(":9092"…

Spring Boot助力:构建响应式论坛网站

3系统分析 3.1可行性分析 通过对本论坛网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本论坛网站采用SSM框架&#xff0c;JAVA作为开发语言&#xff0c;是…

华为云CodeArts Pipeline架构与内容双重优化,高效助力持续交付!

点击下方链接进入帮助中心 成长地图_流水线 CodeArts Pipeline_华为云

unity学习-全局光照(GI)

在全局光照&#xff08;Lighting&#xff09;界面有两个选项 Realtime Light&#xff08;实时光照&#xff09;&#xff1a;在项目中会提前计算好光照以及阴影的程序&#xff0c;当你需要调用实时全局光照的时候会将程序调用出来使用 Mixed Light&#xff08;烘焙光照&#x…

HBuilder X 中Vue.js基础使用1(三)

一、 模板语法 Vue 使用一种基于 HTML 的模板语法&#xff0c;使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML&#xff0c;可以被符合规范的浏览器和 HTML 解析器解析。 英文官网: Vue.js - The Progressive JavaScript Fr…

DPRNN 学习

DPRNN介绍 双路径循环语音分离神经网络&#xff08;Dual-Path RNN&#xff09;由三个处理阶段组成, 编码器、分离和解码器。首先&#xff0c;编码器模块用于将混合波形的短段转换为它们在中间特征空间中的对应表示。然后&#xff0c;该表示用于在每个时间步估计每个源的乘法函…

HCIP-HarmonyOS Application Developer 习题(十四)

&#xff08;多选&#xff09;1、HarmonyOs为应用提供丰富的Al(Artificial Intelligence)能力&#xff0c;支持开箱即用。下列哪些是它拥有的AI能力? A、通用文字识别 B、词性标注 C、实体识别 D、语音播报 答案&#xff1a;ABCD 分析&#xff1a; AI能力简介二维码生成根据开…

(JAVA)贪心算法、加权有向图与求得最短路径的基本论述与实现

1. 贪心算法 1.1 贪心算法的概述&#xff1a; 贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。 贪心算法的特点是一步一步地进行&#xff0c;常以当前情况为基础根据某个优化测度作最优选择&#xff0c;而不考虑各种可能的整体情况&#xff0c;省去了为找最优…

【深度学习中的注意力机制6】11种主流注意力机制112个创新研究paper+代码——加性注意力(Additive Attention)

【深度学习中的注意力机制6】11种主流注意力机制112个创新研究paper代码——加性注意力&#xff08;Additive Attention&#xff09; 【深度学习中的注意力机制6】11种主流注意力机制112个创新研究paper代码——加性注意力&#xff08;Additive Attention&#xff09; 文章目录…

【C#】调用本机AI大模型流式返回

【python】AI Navigator的使用及搭建本机大模型_anaconda ai navigator-CSDN博客 【Python】AI Navigator对话流式输出_python ai流式返回-CSDN博客 前两章节我们讲解了使用AI Navigator软件搭建本机大模型&#xff0c;并使用python对大模型api进行调用&#xff0c;使其流式返…

“智能科研写作:结合AI与ChatGPT提升SCI论文和基金申请质量“

基于AI辅助下的高效高质量SCI论文撰写及投稿实践 科学研究的核心在于将复杂的思想和实验成果通过严谨的写作有效地传递给学术界和工业界。对于研究生、青年学者及科研人员&#xff0c;如何高效撰写和发表SCI论文&#xff0c;成为提升学术水平和科研成果的重要环节。系统掌握从…

SAP_FICO模块-资产减值功能对折旧和残值的影响

一、业务背景 由于财务同事没注意&#xff0c;用总账给资产多做了一笔凭证&#xff0c;导致该资产金额虚增&#xff0c;每个月的折旧金额也虚增&#xff1b;现在财务的需求是怎么操作可以进行资产减值&#xff0c;并且减少每个月计提的折旧&#xff1b; 二、实现方式 通过事务码…

qt EventFilter用途详解

一、概述 EventFilter是QObject类的一个事件过滤器&#xff0c;当使用installEventFilter方法为某个对象安装事件过滤器时&#xff0c;该对象的eventFilter函数就会被调用。通过重写eventFilter方法&#xff0c;开发者可以在事件处理过程中进行拦截和处理&#xff0c;实现对事…

go 语言 Gin Web 框架的实现原理探究

Gin 是一个用 Go (Golang) 编写的 Web 框架&#xff0c;性能极优&#xff0c;具有快速、支持中间件、crash处理、json验证、路由组、错误管理、内存渲染、可扩展性等特点。 官网地址&#xff1a;https://gin-gonic.com/ 源码地址&#xff1a;https://github.com/gin-gonic/gi…

Shell重定向输入输出

我的后端学习大纲 我的Linux学习大纲 重定向介绍 标准输入介绍 从键盘读取用户输入的数据&#xff0c;然后再把数据拿到Shell程序中使用&#xff1b; 标准输出介绍 Shell程序产生的数据&#xff0c;这些数据一般都是呈现到显示器上供用户浏览查看; 默认输入输出文件 每个…

前OpenAI首席技术官为新AI初创公司筹资;我国发布首个应用临床眼科大模型 “伏羲慧眼”|AI日报

文章推荐 2024人工智能报告.zip &#xff5c;一文迅速了解今年的AI界都发生了什么&#xff1f; 今日热点 据报道&#xff0c;前OpenAI首席技术官Mira Murati正在为一家新的AI初创公司筹集资金 据路透社报道&#xff0c;上个月宣布离职的OpenAI首席技术官Mira Murati正在为一…