有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java追加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) 个答案

  1. # 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对象是一回事。第二件事是评估这些脚本。如果您总是立即对script1script2进行评估,那么您只需要:

    compiledScript1.eval(bindings);
    compiledScript2.eval(bindings);
    

    但是script1可能会返回一些值,根据该值,您可以决定是否应该对script2进行评估。假设script1返回一个Integer,我将仅在返回值大于1时计算script2

    Integer returnedValue = (Integer) compiledScript1.eval(bindings);
    if (returnedValue > 1) {
        compiledScript2.eval(bindings);
    }
    

    或者,您可以在运行script1之后基于绑定值。假设script1修改绑定ab,并将两者设置为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都包含对同一个引擎的引用,因此您可以引用在先前评估的脚本中定义的函数