Append CompiledScript 或添加两个 CompiledScript
Append CompiledScript or add two CompiledScript
您好,我正在使用 Groovy
引擎来评估某个脚本。问题是执行时间有点大,所以我想把我的脚本分成两个脚本。第一个是静态的,可以在 @PostConstruct
方法中编译,第二个是变量,它取决于用户选择的一些参数。这就是我想要做的:
Bindings bindings;
CompiledScript scriptC;
String script1="Static Script";
String script2="Variable Script";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
scriptC = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
scriptC += ((Compilable) engine).compile(script2);//Please note the += operator
或
Bindings bindings;
CompiledScript scriptC;
String script1="Static Script";
String script2="Variable Script";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
scriptC = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
scriptC.append(((Compilable) engine).compile(script2));//Please note the append function
这两个代码肯定不起作用,我用它们只是为了说明我正在尝试做什么。是否可以将两个脚本合并为一个脚本?
你不能像那样组合两个 CompiledScript
对象。如果涉及到 Groovy - 当 Groovy 脚本被编译时,它会创建一个 class 来扩展 groovy.lang.Script
,其中包含一些方法。在这种情况下,将两个脚本相互添加意味着合并两个 Java classes.
考虑将两个脚本分开评估作为替代方案。看看下面的例子:
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("Groovy");
final Bindings bindings = new SimpleBindings();
bindings.put("a", 3);
final String script1 = "println 'Running first script...'; def c = 2; def d = c + a; return d";
final CompiledScript compiledScript1 = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
final String script2 = "println 'Running second script...';";
final CompiledScript compiledScript2 = ((Compilable) engine).compile(script2);
Integer returnedValue = (Integer) compiledScript1.eval(bindings);
System.out.println("Returned value from the first script: " + returnedValue);
if (returnedValue > 1) {
compiledScript2.eval(bindings);
}
}
}
创建 CompiledScript
对象是一回事。第二件事是评估这些脚本。如果您总是立即评估 script1
和 script2
,那么您只需要:
compiledScript1.eval(bindings);
compiledScript2.eval(bindings);
但是 script1
可能 return 一些值,您可以根据该值决定是否应评估 script2
。假设 script1
return 是一个 Integer
,只有当 returned 值大于 1 时,我才会计算 script2
:
Integer returnedValue = (Integer) compiledScript1.eval(bindings);
if (returnedValue > 1) {
compiledScript2.eval(bindings);
}
或者,您可以基于 运行ning script1
之后的绑定值。假设 script1
修改绑定 a
和 b
并将两者都设置为 true
(假设它们持有 boolean
类型):
compiledScript1.eval(bindings);
if (bindings.get("a") && bindings.get("b")) {
compiledScript2.eval(bindings);
}
正在从 script2
调用 script1
中定义的函数
假设script1
定义如下:
import groovy.json.JsonOutput
def json(Map map) {
return new JsonOutput().toJson(map)
}
println json([test: 1])
如果您必须在 script2
中调用 json(map)
函数 - 您可以这样做。看看这个例子:
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("Groovy");
final Bindings bindings = new SimpleBindings();
bindings.put("a", 3);
final String script1 = "import groovy.json.JsonOutput\n" +
"\n" +
"def json(Map map) {\n" +
" return new JsonOutput().toJson(map)\n" +
"}\n" +
"\n" +
"println json([test: 1])";
final CompiledScript compiledScript1 = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
final String script2 = "println 'Running second script...'; println json([test: 2]);";
final CompiledScript compiledScript2 = ((Compilable) engine).compile(script2);
compiledScript1.eval(bindings);
compiledScript2.eval(bindings);
}
}
script2
定义为:
println 'Running second script...';
println json([test: 2]);
当你运行它时,你会在控制台中看到:
{"test":1}
Running second script...
{"test":2}
前两行来自script1
,最后一行由script2
生成。请记住,两个 CompiledScript
都持有对同一引擎的引用,因此您可以引用在先前评估的脚本中定义的函数。
您好,我正在使用 Groovy
引擎来评估某个脚本。问题是执行时间有点大,所以我想把我的脚本分成两个脚本。第一个是静态的,可以在 @PostConstruct
方法中编译,第二个是变量,它取决于用户选择的一些参数。这就是我想要做的:
Bindings bindings;
CompiledScript scriptC;
String script1="Static Script";
String script2="Variable Script";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
scriptC = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
scriptC += ((Compilable) engine).compile(script2);//Please note the += operator
或
Bindings bindings;
CompiledScript scriptC;
String script1="Static Script";
String script2="Variable Script";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
scriptC = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
scriptC.append(((Compilable) engine).compile(script2));//Please note the append function
这两个代码肯定不起作用,我用它们只是为了说明我正在尝试做什么。是否可以将两个脚本合并为一个脚本?
你不能像那样组合两个 CompiledScript
对象。如果涉及到 Groovy - 当 Groovy 脚本被编译时,它会创建一个 class 来扩展 groovy.lang.Script
,其中包含一些方法。在这种情况下,将两个脚本相互添加意味着合并两个 Java classes.
考虑将两个脚本分开评估作为替代方案。看看下面的例子:
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("Groovy");
final Bindings bindings = new SimpleBindings();
bindings.put("a", 3);
final String script1 = "println 'Running first script...'; def c = 2; def d = c + a; return d";
final CompiledScript compiledScript1 = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
final String script2 = "println 'Running second script...';";
final CompiledScript compiledScript2 = ((Compilable) engine).compile(script2);
Integer returnedValue = (Integer) compiledScript1.eval(bindings);
System.out.println("Returned value from the first script: " + returnedValue);
if (returnedValue > 1) {
compiledScript2.eval(bindings);
}
}
}
创建 CompiledScript
对象是一回事。第二件事是评估这些脚本。如果您总是立即评估 script1
和 script2
,那么您只需要:
compiledScript1.eval(bindings);
compiledScript2.eval(bindings);
但是 script1
可能 return 一些值,您可以根据该值决定是否应评估 script2
。假设 script1
return 是一个 Integer
,只有当 returned 值大于 1 时,我才会计算 script2
:
Integer returnedValue = (Integer) compiledScript1.eval(bindings);
if (returnedValue > 1) {
compiledScript2.eval(bindings);
}
或者,您可以基于 运行ning script1
之后的绑定值。假设 script1
修改绑定 a
和 b
并将两者都设置为 true
(假设它们持有 boolean
类型):
compiledScript1.eval(bindings);
if (bindings.get("a") && bindings.get("b")) {
compiledScript2.eval(bindings);
}
正在从 script2
调用 script1
中定义的函数
假设script1
定义如下:
import groovy.json.JsonOutput
def json(Map map) {
return new JsonOutput().toJson(map)
}
println json([test: 1])
如果您必须在 script2
中调用 json(map)
函数 - 您可以这样做。看看这个例子:
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
public class ScriptTest {
public static void main(String[] args) throws ScriptException {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("Groovy");
final Bindings bindings = new SimpleBindings();
bindings.put("a", 3);
final String script1 = "import groovy.json.JsonOutput\n" +
"\n" +
"def json(Map map) {\n" +
" return new JsonOutput().toJson(map)\n" +
"}\n" +
"\n" +
"println json([test: 1])";
final CompiledScript compiledScript1 = ((Compilable) engine).compile(script1);
//Execute some instruction to generate 'script2'
final String script2 = "println 'Running second script...'; println json([test: 2]);";
final CompiledScript compiledScript2 = ((Compilable) engine).compile(script2);
compiledScript1.eval(bindings);
compiledScript2.eval(bindings);
}
}
script2
定义为:
println 'Running second script...';
println json([test: 2]);
当你运行它时,你会在控制台中看到:
{"test":1}
Running second script...
{"test":2}
前两行来自script1
,最后一行由script2
生成。请记住,两个 CompiledScript
都持有对同一引擎的引用,因此您可以引用在先前评估的脚本中定义的函数。