你不能像那样组合两个CompiledScript
对象。如果涉及到 Groovy - 当 Groovy 脚本被编译时,它会创建一个类,该类groovy.lang.Script
在内部扩展了一些方法。在这种情况下,将两个脚本相互添加意味着合并两个 Java 类。
考虑单独评估两个脚本作为替代方案。看看下面的例子:
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
可能会返回一些值,并且基于该值您可以决定是否script2
应该评估。假设script1
返回一个Integer
,我将script2
仅在返回值大于 1 时进行评估:
Integer returnedValue = (Integer) compiledScript1.eval(bindings);
if (returnedValue > 1) {
compiledScript2.eval(bindings);
}
或者,您可以在运行后基于绑定值script1
。假设script1
修改绑定a
并将b
两者都设置为true
(假设它们持有boolean
类型):
compiledScript1.eval(bindings);
if (bindings.get("a") && bindings.get("b")) {
compiledScript2.eval(bindings);
}
调用script1
from中定义的函数script2
假设script1
定义如下:
import groovy.json.JsonOutput
def json(Map map) {
return new JsonOutput().toJson(map)
}
println json([test: 1])
如果你必须在里面调用json(map)
函数script2
- 你可以做到。看看这个例子:
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
持有对同一引擎的引用,因此您可以引用在先前评估的脚本中定义的函数。