问题:SCALA 中使用ScriptEngine动态调用脚本时,效率很低,主要瓶颈是初始化SCALA环境和编译脚本。而ScriptEngine提供了预编译的方法,但scala脚本无法使用BINDINGS进行传参,这点我已经反复测试。详情如下:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("scala");
Bindings bindings = engine.createBindings();
bindings.put("firstVal", 209);
bindings.put("secondVal", 30);
bindings.put("sumUtil", new Sum());
CompiledScript script = ((Compilable)engine).compile(
"var sum = sumUtil.asInstanceOf[com.myutils.Sum]\n"+
"var firstInt = firstVal.asInstanceOf[Integer]\n"+
"var secondInt = secondVal.asInstanceOf[Integer]\n"+
"sum.add(firstInt, secondInt)\n"
);
Integer res1 = (Integer) script.eval(bindings);
System.out.println("Result 1: "+res1);
bindings = engine.createBindings();
bindings.put("firstVal", 2);
bindings.put("secondVal", 3);
Integer res2 = (Integer) script.eval(bindings);
System.out.println("Result 2: "+res2);
执行结果如下:
firstVal: Object = 209
secondVal: Object = 30
sumUtil: Object = com.myutils.Sum@71136646
Result 1: 239
firstVal: Object = 2
secondVal: Object = 3
Result 2: 239
如何动态的给编译好的程序绑定变量呢,我提供了以下方法绕行:
val m =new ScriptEngineManager()
val engine = m.getEngineByName("scala")
val settings = engine.asInstanceOf[scala.tools.nsc.interpreter.IMain].settings
settings.usejavacp.value =true
val compilable: Compilable = engine.asInstanceOf[Compilable]
val scripts =
"""
|import scala.collection.mutable
|val helloWorld = (gays:mutable.Map[String, Any]) => {
| gays.foreach(gay =>{
| println(gay)
| })
|
| gays
|}
|helloWorld
""".stripMargin
val compiledScript: CompiledScript = compilable.compile(scripts)
val unit:AnyRef = compiledScript.eval()
println(unit.getClass)
val s = unit.asInstanceOf[Function1[mutable.Map[String, Any], AnyRef]](mutable.Map[String, Any]("yjd" ->"hello"))
println(s)
结果如下
class $line3.$read$$iw$$iw$$anon$1$$anonfun$1
(yjd,hello)
Map(yjd -> hello)