概述
PreCompiler类继承HashTreeTraverser类,重写addNode方法来解析jmx文件中引用的变量和内置函数。
针对本地部署还是分布式部署方式分别被StandardJMeterEngine类和ClientJMeterEngine类调用。
源码分析
构造函数
针对本地部署,被StandardJMeterEngine类调用
代码语言:txt复制 public PreCompiler() {
replacer = new ValueReplacer();
isClientSide = false; // 本地部署为false
}
针对分布式部署,被ClientJMeterEngine类调用
代码语言:txt复制 public PreCompiler(boolean remote) {
replacer = new ValueReplacer();
isClientSide = remote; // 分布式部署为true
}
主要变量
代码语言:txt复制 // 参数和内置函数替换的操作类
private final ValueReplacer replacer;
private final boolean isClientSide;
// 分布式部署用到的变量
private JMeterVariables clientSideVariables;
主要方法
addNode
重写addNode方法,解析jmx文件中引用的变量和内置函数,并存储到JMeterContext线程类中。
代码语言:txt复制 public void addNode(Object node, HashTree subTree) {
// 分布式部署
if(isClientSide) {
// 判断需要参数替换的元素节点类型
if(node instanceof ResultCollector || node instanceof Backend) {
try {
// 进行参数替换
replacer.replaceValues((TestElement) node);
} catch (InvalidVariableException e) {
log.error("invalid variables in node {}", ((TestElement)node).getName(), e);
}
}
if (node instanceof TestPlan) {
this.clientSideVariables = createVars((TestPlan)node);
}
if (node instanceof Arguments) {
// Don't store User Defined Variables in the context for client side
Map<String, String> args = createArgumentsMap((Arguments) node);
clientSideVariables.putAll(args);
}
} else { // 本地部署
if(node instanceof TestElement) {
try {
// 进行参数替换
replacer.replaceValues((TestElement) node);
} catch (InvalidVariableException e) {
log.error("invalid variables in node {}", ((TestElement)node).getName(), e);
}
}
//将testplan中的参数存入JMeterVariables
if (node instanceof TestPlan) {
JMeterVariables vars = createVars((TestPlan)node);
JMeterContextService.getContext().setVariables(vars);
}
//将Arguments中的参数存入JMeterVariables
if (node instanceof Arguments) {
Map<String, String> args = createArgumentsMap((Arguments) node);
JMeterContextService.getContext().getVariables().putAll(args);
}
}
}
createVars
获取testPlan中自定义的变量
代码语言:txt复制 private JMeterVariables createVars(TestPlan testPlan) {
// 设置RunningVersion为true
testPlan.prepareForPreCompile(); //A hack to make user-defined variables in the testplan element more dynamic
// 获取testPlan中定义的变量
Map<String, String> args = testPlan.getUserDefinedVariables();
// 将变量存入ValueReplacer类
replacer.setUserDefinedVariables(args);
JMeterVariables vars = new JMeterVariables();
vars.putAll(args);
return vars;
}
createArgumentsMap
获取用户自定义变量,jmx文件中testclass名为Arguments的类
代码语言:txt复制 private Map<String, String> createArgumentsMap(Arguments arguments) {
// 设置RunningVersion为true
arguments.setRunningVersion(true);
// 获取用户自定义变量列表
Map<String, String> args = arguments.getArgumentsAsMap();
// 将变量存入ValueReplacer类
replacer.addVariables(args);
return args;
}
getClientSideVariables
获取分布式部署用到的变量
代码语言:txt复制 public JMeterVariables getClientSideVariables() {
return clientSideVariables;
}