Java ScriptEngineManager类使用

在开发过程中,经常会需要在程序运行时使用脚本,在java中可以使用诸如Groovy等运行在JVM上的脚本,需要对应添加依赖。也可以直接使用java脚本(使用janino库来进行编译,或者使用JavaCompile API  ToolProvider 链接)。通常我们使用的脚本都是解释型脚本,其实java本来就自带了脚本相关的类库。即  ScriptEngineManager 类,通常我们使用该类来执行javascript脚本,今天就简单来使用一下。

 

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JavaScriptTest {
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        long l = System.currentTimeMillis();
        for (int i = 0; i < 1000 ; i++) {
            String script = "function run(arg){if (arg>500){return 0}else{return arg}}";
            System.out.println(jsRun("run", script, i));
        }
        System.out.println("耗时:"+String.valueOf(System.currentTimeMillis() - l));

    }

    /**
     *
     * @param methodName js脚本方法名
     * @param script  js 脚本内容
     * @param args js方法参数
     * @return
     * @throws ScriptException
     * @throws NoSuchMethodException
     */
    public static Object jsRun(String methodName, String script, Object... args) throws ScriptException, NoSuchMethodException {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine javaScriptEngine = scriptEngineManager.getEngineByName("JavaScript");
        javaScriptEngine.eval(script);
        Invocable inv = (Invocable) javaScriptEngine;
        return  inv.invokeFunction(methodName, args);


    }
}

如上我们就执行了一段javascript的代码,实际执行了1000次,总耗时:3332毫秒 (基本就是3秒左右,跟机器的性能有关系,我用台式机执行在2.5秒左右,就不放截图了)

由此可见使用java执行js脚本是有性能损耗的,但是如果我们能提前编译脚本代码的话,情况又是怎么样呢

import javax.script.*;

public class CompileJavaScriptTest {
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        long l = System.currentTimeMillis();
        String script = "function run(arg){if (arg>500){return 0}else{return arg}}";
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine javaScriptEngine = scriptEngineManager.getEngineByName("JavaScript");
        Compilable compilable = (Compilable) javaScriptEngine;
        CompiledScript compileScript = compilable.compile(script);
        for (int i = 0; i < 1000; i++) {
            System.out.println(jsRun("run", compileScript, i));
        }
        System.out.println("耗时:" + String.valueOf(System.currentTimeMillis() - l));

    }

    /**
     * @param methodName js脚本方法名
     * @param compiledScript js 编译脚本对象
     * @param args       js方法参数
     * @return
     * @throws ScriptException
     * @throws NoSuchMethodException
     */
    public static Object jsRun(String methodName, CompiledScript compiledScript, Object... args) throws ScriptException, NoSuchMethodException {

        compiledScript.eval();
        Invocable inv = (Invocable) compiledScript.getEngine();
        return inv.invokeFunction(methodName, args);


    }
}

上面的代码是先编译脚本,再执行脚本,同样的js脚本,同样是执行1000次,耗时是476毫秒,可见比直接执行速度要快的多

 

posted @ 2022-04-18 15:03  陈无问  阅读(3725)  评论(0编辑  收藏  举报