我正在研究将基于犀牛的巨型项目转移到nashorn的可能性。该项目有一千个范围(〜实例)在一个rhino编译脚本(10k + javascript行)中运行。
我知道该怎么做:
我可以用Rhino做什么并且希望能够使用Nashorn的例子:
String SOURCE = "var i = 0; function add(a) { i += a; return i; }";
System.out.println("=== RHINO ===");
Context cx = Context.enter();
cx.setOptimizationLevel(Context.FEATURE_STRICT_EVAL); // optimization level 9
Script script = cx.compileString(SOURCE, "mySource", 1, null); // compile once
Scriptable scope1 = cx.initStandardObjects(); // 1st re-use
Scriptable scope2 = cx.initStandardObjects(); // 2nd re-use
script.exec(cx, scope1);
script.exec(cx, scope2);
Function add1 = (Function) scope1.get("add", scope1);
Function add2 = (Function) scope2.get("add", scope2);
try {
Object r1 = add1.call(cx, scope1, scope1, new Object[]{6});
System.out.println("result1=" + r1); // print 6
r1 = add1.call(cx, scope1, scope1, new Object[]{4});
System.out.println("result1=" + r1); // print 10
} catch (Exception ex) {
ex.printStackTrace();
}
try {
Object r2 = add2.call(cx, scope2, scope2, new Object[]{9});
System.out.println("result2=" + r2); // prints 9
r2 = add2.call(cx, scope2, scope2, new Object[]{3});
System.out.println("result2=" + r2); // prints 12
} catch (Exception ex) {
ex.printStackTrace();
}
Context.exit();
在上面的示例中,我编译脚本一次,并使用多个范围来隔离我的不同执行实例。 我怎么能和Nashorn做这样的事情?请记住,在我的真实项目中,我想调用更复杂的函数,这些函数将在参数中使用javascript或java实例。
提前感谢您的帮助。
答案 0 :(得分:0)
Nashorn支持loadWithNewGlobal原语(https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-loadWithNewGlobal)。这个原语允许你在新的全局范围中加载脚本 - 每个范围都有自己的“对象”,“功能”等定义。看来这可能对你的用例有所帮助。还有范围内的对象方法/属性访问支持。也就是说,你可以向/从不同范围内评估的脚本传递和返回对象 - 适当的包装/镜像由Nashorn负责。