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毫秒,可见比直接执行速度要快的多