JMeter源码解析之NewDriver.java(二)完结

JMeter源码解析之NewDriver.java(二)完结

NewDriver.java主要作用

JMeter程序入口:JMeter的主类-设置初始类路径和加载程序。

文件路径

路径地址:…\apache-jmeter-5.1\src\core\org\apache\jmeter\NewDriver.java

关于Main内容中的代码解析

 /*** The main program which actually runs JMeter.* 实际运行JMeter的主程序* @param args*            the command line arguments*/public static void main(String[] args) {/***  当启动加载的异常内容里面,没有相应的报错时,程序启动,否则报错。* EXCEPTIONS_IN_INIT的数据主要来源 EXCEPTIONS_IN_INIT.add(new Exception("Error adding jar:"+libJar.getAbsolutePath(), e));*/if(!EXCEPTIONS_IN_INIT.isEmpty()) {System.err.println("Configuration error during init, see exceptions:"+exceptionsToString(EXCEPTIONS_IN_INIT)); // NOSONAR Intentional System.err use} else {//通过将 loader 设置为当前线程的上下文类加载器,可以将自定义的类加载器 loader 用于当前线程中的类加载操作,从而实现需要使用特定类加载器加载的类或资源Thread.currentThread().setContextClassLoader(loader);//设置日志环境系统属性,简单的可以连接为,当我们入参为-j D:\1\1\1.log,我们会在对应的路径D:\1\1\生成1.log日志setLoggingProperties(args);try {// Only set property if it has not been set explicitely// 设置系统属性变成noGUI模式运行if(System.getProperty(HEADLESS_MODE_PROPERTY) == null && shouldBeHeadless(args)) {System.setProperty(HEADLESS_MODE_PROPERTY, "true");}/** 这段代码通过反射加载和执行了org.apache.jmeter.JMeter类的启动方法。* 它首先加载主类,然后使用反射创建主类的实例,接着获取start方法并通过反射执行该方法,以启动Apache JMeter。* */Class<?> initialClass = loader.loadClass("org.apache.jmeter.JMeter");// $NON-NLS-1$Object instance = initialClass.getDeclaredConstructor().newInstance();Method startup = initialClass.getMethod("start", new Class[] { new String[0].getClass() });// $NON-NLS-1$startup.invoke(instance, new Object[] { args });} catch(Throwable e){ // NOSONAR We want to log home directory in case of exceptione.printStackTrace(); // NOSONAR No logger at this stepSystem.err.println("JMeter home directory was detected as: "+JMETER_INSTALLATION_DIRECTORY); // NOSONAR Intentional System.err use}}}

上述代码中我们可以发现一有趣的代码:

 Class<?> initialClass = loader.loadClass("org.apache.jmeter.JMeter");// $NON-NLS-1$Object instance = initialClass.getDeclaredConstructor().newInstance();Method startup = initialClass.getMethod("start", new Class[] { new String[0].getClass() });// $NON-NLS-1$startup.invoke(instance, new Object[] { args });

然后就比较好奇,为啥我们不直接引用JMeter这个类,然后直接调用里调用里面的start方法呢?所以针对这个去查询了下资料,得到如下回答:

使用反射方式调用方法和直接调用类的方法有以下不同点和好处

1.动态性:通过反射,可以在运行时动态地获取类和方法的信息,而不需要在编译时确定。这样可以实现更加灵活的代码逻辑和动态的代码调用。

2.解耦合:通过反射,可以在不知道具体类的情况下调用其方法。这样可以实现松耦合的代码结构,提高代码的可维护性和可扩展性。

3.功能扩展:使用反射可以实现一些无法在编译时确定的功能,比如动态添加、修改和删除类的属性、方法等。

4.框架开发:很多框架和库都使用反射来实现通用的功能,比如Spring框架的IOC容器、Hibernate框架的ORM映射等。通过反射可以实现通用的代码模块,提高开发效率和代码复用性。

需要注意的是,使用反射可能会带来一些性能上的损失,因为反射调用的过程需要额外的计算和处理。但是在很多情况下,这种性能损失可以接受,特别是在需要动态性和灵活性的场景下。因此,在选择使用反射还是直接调用类的方法时,需要综合考虑具体的需求和性能要求。

关于setLoggingProperties内容中的代码解析

/** Set logging related system properties.* 设置与日志记录相关的系统属性*/private static void setLoggingProperties(String[] args) {//获取NoGUI时输入的命令中-j后面的参数,如-j D:\1\1\1.log,返回的结果是:D:\1\1\1.logString jmLogFile = getCommandLineArgument(args, 'j', "jmeterlogfile");// $NON-NLS-1$ $NON-NLS-2$if (jmLogFile != null && !jmLogFile.isEmpty()) {jmLogFile = replaceDateFormatInFileName(jmLogFile);//System.setProperty()方法用于设置系统属性。系统属性是一些键值对,用于存储关于操作系统和应用程序的配置信息System.setProperty(JMETER_LOGFILE_SYSTEM_PROPERTY, jmLogFile);// $NON-NLS-1$} else if (System.getProperty(JMETER_LOGFILE_SYSTEM_PROPERTY) == null) {// $NON-NLS-1$System.setProperty(JMETER_LOGFILE_SYSTEM_PROPERTY, "jmeter.log");// $NON-NLS-1$ $NON-NLS-2$}//日志类型,但是目前网上搜到的资料,并没有确切的-i相关的参数进行入参,可以理解为当前就是默认的日志格式String jmLogConf = getCommandLineArgument(args, 'i', "jmeterlogconf");// $NON-NLS-1$ $NON-NLS-2$File logConfFile = null;if (jmLogConf != null && !jmLogConf.isEmpty()) {logConfFile = new File(jmLogConf);} else if (System.getProperty("log4j.configurationFile") == null) {// $NON-NLS-1$logConfFile = new File("log4j2.xml");// $NON-NLS-1$if (!logConfFile.isFile()) {logConfFile = new File(JMETER_INSTALLATION_DIRECTORY, "bin" + File.separator + "log4j2.xml");// $NON-NLS-1$ $NON-NLS-2$}}if (logConfFile != null) {System.setProperty("log4j.configurationFile", logConfFile.toURI().toString());// $NON-NLS-1$}}

关于getCommandLineArgument内容中的代码解析

 /** Find command line argument option value by the id and name.* 根据id和名称查找命令行参数选项值* 输入的JMeter命令比如是这样:jmeter -n -t C:\Users\Desktop\tokenZB.jmx -l D:\1\1\1.jtl -e -o D:\1\1\report -j D:\1\1\1.log* 然后我们可以得到一个String类型数组,内容就是这样的:* new String[]{"-n","-t","C:\\Users\\Desktop\\tokenZB.jmx","-l","D:\\1\\1\\1.jtl","-e","-o","D:\\1\\1\\report","-j","D:\\1\\1\\1.log"};*/private static String getCommandLineArgument(String[] args, int id, String name) {//获取对应的命令后面的参数,比如-j,为配置日志路径,则通过传入id获取对应-j后面的参数内容,“--”也是一样的道理final String shortArgName = "-" + ((char) id);// $NON-NLS-1$final String longArgName = "--" + name;// $NON-NLS-1$String value = null;for (int i = 0; i < args.length; i++) {//获取某个参数后面指定的值,比如-j后面的值,并且此处是可以进行指定参数与自己的输入的参数连写,JMeter也会进行自动识别if ((shortArgName.equals(args[i]) && i < args.length - 1)|| longArgName.equals(args[i])) {if (!args[i + 1].startsWith("-")) {// $NON-NLS-1$value = args[i + 1];}break;//比如原则上-j D:\1\\1\1.log,但是如果我们不小心写成了-jD:\1\\1\1.log,JMeter可以读取-j后面的参数,即:D:\1\\1\1.log} else if (!shortArgName.equals(args[i]) && args[i].startsWith(shortArgName)) {value = args[i].substring(shortArgName.length());break;}}return value;}

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

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

相关文章

8-异常与错误

8-异常与错误 1、简介2、异常处理2.1 抛出异常2.2 捕获异常2.3 匹配顺序 3、异常说明4、构造函数中的异常5、析构函数中的异常6、标准库异常 1、简介 在程序编码过程中难免会出现错误&#xff0c;主要有&#xff1a;语法错误、逻辑错误、功能错误等&#xff0c;当我们面对以上…

密闭空间作业应如何做好安全防护?

在现代工业与日常工作中&#xff0c;密闭空间作业已逐渐成为许多行业不可或缺的一部分。然而&#xff0c;这些看似寻常的空间却隐藏着诸多不为人知的风险。从窒息性气体到易燃易爆物质&#xff0c;从物理性危险到心理压力&#xff0c;每一项都足以威胁到作业人员的生命安全。因…

Llama模型家族之RLAIF 基于 AI 反馈的强化学习(六) RLAIF 代码实战

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

主键UUID和数据库自增ID怎么选择?

一、前言 最近在建表选择主键的时候有些纠结&#xff0c;我们经常使用的主键有两种UUID和自增ID&#xff0c;不知道选哪一种好。之前一直没有总结过这两种主键的区别&#xff0c;于是今天去总结了一下这两种主键的区别、优缺点&#xff0c;以便为我们以后主键选择提供一些参考。…

字符串匹配算法(三)Trie树算法

文章目录 Trie树的简介Trie树定义Trie树的实现 代码实现 Trie树的简介 Trie树定义 Trid树&#xff0c;也叫”字典树“。它是一个树形结构。专门处理字符串匹配的数据结构&#xff0c;用来解决字符串集中快速查找某个字符串的问题。 Trie 树的本质&#xff0c;就是利用字符串之…

LeetCode503:下一个更大元素Ⅱ

题目描述 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这…

记录一次云服务器无法连接的排查过程

运行环境&#xff1a;阿里云服务器 故障外显原因&#xff1a;登录失败,操作系统禁用了密码登录方式 控制台监控数据显示云盘读写BPS拉满了 因为之前问过线上售后&#xff0c;让安装了atop监控&#xff0c;&#xff0c;所以先打开atop日志&#xff1a; atop -r /var/log/atop…

自动驾驶中的长尾问题

自动驾驶中的长尾问题 定义 长尾问题&#xff08;Long-Tail Problem&#xff09;是指在数据分布中&#xff0c;大部分的数据集中在少数类别上&#xff0c;而剩下的大多数类别却只有少量的数据。这种数据分布不平衡的现象在许多实际应用中广泛存在&#xff0c;特别是在自动驾驶…

音视频开发—H265相关概念和压缩原理详解(GOP、宏块、帧内压缩、帧间压缩)

文章目录 1.什么是GOP&#xff1f;1.1 GOP介绍1.2.GOP中I帧/B帧/P帧1.3.I帧和IDR的区别联系I帧&#xff08;Intra Frame&#xff09;IDR帧&#xff08;Instantaneous Decoding Refresh Frame&#xff09;区别总结 1.4 帧与分组的关系1.5 SPS与PPSSPS&#xff08;Sequence Param…

【前端视野下的数据库概念探秘】——信息化人员必备知识面试宝典:解码“视图”与“游标”

【前端视野下的数据库概念探秘】——信息化人员必备知识&面试宝典&#xff1a;解码“视图”与“游标” 视图&#xff1a;数据的魔法透镜基本概念前端为何关心&#xff1f;代码示例&#xff1a;案例一功能使用思路 游标&#xff1a;数据流的指针基础认知前端视角代码示例&am…

竹纤维家装元宇宙:虚拟空间与绿色生活的融合

在全球化和科技迅速发展的今天&#xff0c;元宇宙作为一种全新的互联网应用和社会形态&#xff0c;正逐步渗透到人们生活的各个方面。特别是在家装行业&#xff0c;竹纤维作为一种新型环保材料&#xff0c;结合元宇宙的概念&#xff0c;正在引领一场绿色生活的革命。 ### 一、…

6.5 Go 指针

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

beamer修改超链接颜色报错

beamer修改超链接颜色报错 使用 \usepackage[colorlinkstrue, urlcolorblue]{hyperref} % 只将超链接设置为蓝色设置 url颜色时、会报错 这是因为在使用 LaTeX 的 Beamer 类创建演示文稿时&#xff0c; Beamer 自身已经自动加载了 hyperref 宏包&#xff0c;并对其进行了一些…

EasyExcel之动态表头导出不生效

今天接到一个优化需求&#xff0c;表格导出后的表头顺序和页面不一致&#xff0c;要优化成一致的。根据传入的字段&#xff0c;动态导出数据&#xff0c;并保证顺序。 我看到导出的实体类都有ExcelProperty注解&#xff0c;同时也在官网查看了这注解的含义和使用。 ExcelPrope…

如何在Linux系统中搭建Zookeeper集群

一、概述 ZooKeeper是一个开源的且支持分布式部署的应用程序&#xff0c;是Google的Chubby一个开源的实现&#xff1b;它为分布式应用提供了一致性服务支持&#xff0c;包括&#xff1a;配置维护、域名服务、分布式同步、组服务等。 官网&#xff1a;https://zookeeper.apach…

3D轻量化的三大应用解决方案

老子云平台https://www.laozicloud.com/ 为不同应用场景提供了三大解决方案。 01 单模型轻量化解决方案 数字化时代&#xff0c;越来越多的C2M定制、文旅、电商等行业&#xff0c;为了开拓市场&#xff0c;提升企业竞争力&#xff0c;开始把目光投向产品的3D展示交互。 单模…

ADuM1201可使用π121U31间接替换π122U31直接替换

ADuM1201可使用π121U31间接替换π122U31直接替换 一般低速隔离通信150Kbps电路可使用π121U31&#xff0c;价格优势较大。速度快的有其它型号可达10M,200M,600M。 本文主要介绍ADUM1201,替换芯片π121U31简单资料请访问下行链接 只要0.74元的双通道数字隔离器&#xff0c;1T1…

一个程序员的牢狱生涯(48)男人

星期一 男人 无论发生了什么事,看守所的一切都在按部就班的进行着,墙上的电视在晚上七点钟的时候准时打开,到了所有的号子集体收看“新闻联播”的时间。 号子里除了小x州站在厕所门口没有动外,其他人都安静地做回自己的位置,同样是坐班的姿势,只不过不用‘自我反省’,不…

【字典树(前缀树) 哈希映射 后序序列化】1948. 删除系统中的重复文件夹

本文涉及知识点 字典树&#xff08;前缀树) 哈希映射 后序序列化 LeetCode 1948. 删除系统中的重复文件夹 由于一个漏洞&#xff0c;文件系统中存在许多重复文件夹。给你一个二维数组 paths&#xff0c;其中 paths[i] 是一个表示文件系统中第 i 个文件夹的绝对路径的数组。 …

xmake+xrepo自建仓库添加交叉编译工具链

xmakexrepo自建仓库添加交叉编译工具链 最近想将交叉编译工具链放到xrepo自建仓库中&#xff0c;在xmake中引用&#xff0c;方便多个电脑快速实现交叉编译。 xmake官方文档感觉不够详细&#xff0c;折腾了好久&#xff0c;这里做个记录。 基本步骤如下&#xff1a; 添加自建…