Добавить CompiledScript или добавить два 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
Эти два кода не работают наверняка, я использовал их только для иллюстрации того, что я пытаюсь сделать. Можно ли объединить два скрипта в один?
1 ответ
Вы не можете объединить, как эти два 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
от 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
храните ссылку на тот же движок, чтобы вы могли ссылаться на функции, определенные в ранее оцененных скриптах.