接口
A mapping of key/value pairs, all of whose keys are Strings.
The optional interface implemented by ScriptEngines whose methods compile scripts to a form that can be executed repeatedly without recompilation.
The optional interface implemented by ScriptEngines whose methods allow the invocation of procedures in scripts that have previously been executed.
The interface whose implementing classes are used to connect Script Engines with objects, such as scoped Bindings, in hosting applications.
ScriptEngine is the fundamental interface whose methods must be fully functional in every implementation of this specification.
ScriptEngineFactory is used to describe and instantiate ScriptEngines.
ScriptEngineManager是ScriptEngine的工厂,实例化该工厂的时候会加载可用的所有脚本引擎。从工厂中创建ScriptEngine可以使用getEngineByName、getEngineByExtension或 getEngineByMimeType来得到,只要参数名字能对上。执行脚本调用eval方法即可(效果等同于javascript中的eval)。
使用Java Scripting API的步骤
创建一个 ScriptEngineManager 对象.
从管理器对象中获取 ScriptEngine 对象
使用脚本引擎的 eval() 方法来执行脚本
作用域
单一的作用域是 javax.script.Bindings 接口的实例。这个接口继承自 java.util.Map<String,Object> 接口。一个作用域相当于是成对的名称和值的列表,其中名称不能为空。javax.script.ScriptContext 接口通过为每个作用域关联一个 Bindings 对象来实现对多个作用域的支持。默认情况下,每个脚本应用有自己独立的上下文。默认的脚本上下文至少有一个作用域,这是通过静态属性 ENGINE_SCOPE 来定义的。脚本上下文可以通过 getScopes() 方法来实现对不同作用域的支持。
传递变量
// create a script engine manager
ScriptEngineManager factory =
new
ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName(
"JavaScript"
);
engine.put(
"a"
,
4
);
engine.put(
"b"
,
6
);
try
{
Object maxNum = engine
.eval(
"function max_num(a,b){return (a>b)?a:b;}max_num(a,b);"
);
System.out.println(
"max_num:"
+ maxNum);
}
catch
(Exception e) {
e.printStackTrace();
}
动态调用
通过Invocable接口来多次调用脚本库中的函数,Invocable接口是 ScriptEngine可选实现的接口。
ScriptEngineManager factory =
new
ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName(
"JavaScript"
);
try
{
engine.eval(
"function max_num(a,b){return (a>b)?a:b;}"
);
Invocable invoke = (Invocable) engine;
Object maxNum = invoke.invokeFunction(
"max_num"
,
4
,
6
);
System.out.println(maxNum);
maxNum = invoke.invokeFunction(
"max_num"
,
7
,
6
);
System.out.println(maxNum);
}
catch
(Exception e) {
// TODO: handle exception
}
动态实现接口,调用Java Interface实例
public
interface
JSLib {
public
int
max_num(
int
a,
int
b);
}
// create a script engine manager
ScriptEngineManager factory =
new
ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName(
"JavaScript"
);
try
{
engine.eval(
"function max_num(a,b){return (a>b)?a:b;}"
);
Invocable invoke = (Invocable) engine;
JSLib jslib = invoke.getInterface(JSLib.
class
);
int
maxNum = jslib.max_num(
4
,
6
);
System.out.println(maxNum);
}
catch
(Exception e) {
// TODO: handle exception
}
编译执行
脚本引擎默认是解释执行的,如果需要反复执行脚本,可以使用它的可选接口Compilable来编译执行脚本,以获得更好的性能。
try
{
Compilable compEngine = (Compilable) engine;
CompiledScript script = compEngine
.compile(
"function max_num(a,b){return (a>b)?a:b;}"
);
script.eval();
Invocable invoke = (Invocable) engine;
Object maxNum = invoke.invokeFunction(
"max_num"
,
4
,
6
);
System.out.println(maxNum);
}
catch
(Exception e) {
e.printStackTrace();
}