Java 6 版本就已经引入了 Rhino 引擎用以支持脚本代码运行,而从 Java 8 开始 Nashorn 取代 Rhino 成为 Java 内嵌的 JavaScript 引擎。Nashorn 引擎允许开发人员将 JavaScript 代码嵌入到 Java 中执行,这个特性在复杂的配置系统中有比较大的应用价值,可以满足特定场景下的灵活性要求
以下示例代码可以列出所有脚本引擎工厂的相关属性,可以看到其支持的脚本引擎包括了 JavaScript 等
public static void main(String[] args) {ScriptEngineManager manager = new ScriptEngineManager();
manager.getEngineFactories().forEach(factory ->System.out.printf("Name: %s%n" +
"Version: %s%n" +
"Language name: %s%n" +
"Language version: %s%n" +
"Extensions: %s%n" +
"Mime types: %s%n" +
"Names: %s%n",
factory.getEngineName(),
factory.getEngineVersion(),
factory.getLanguageName(),
factory.getLanguageVersion(),
factory.getExtensions(),
factory.getMimeTypes(),
factory.getNames()));
}
2. 脚本引擎的使用Java 脚本引擎 API 中最主要的是ScriptEngineManager
,开发者可以通过这个类获取当前 Java 版本所支持的所有脚本引擎,具体获取脚本引擎的方法有以下3种:
ScriptEngineManager manager = new ScriptEngineManager();
// getEngineByExtension 的参数就是 Extensions:[js]中任一个
ScriptEngine engine = manager.getEngineByExtension("js");
ScriptEngineManager manager = new ScriptEngineManager();
// getEngineByMimeType 的参数可以是 Mime types: [application/javascript, application/ecmascript, text/javascript, text/ecmascript]中的任一个
ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
ScriptEngineManager manager = new ScriptEngineManager();
// getEngineByName 的参数可以是 Names: [js, rhino, JavaScript, javascript, ECMAScript, ecmascript]
// 中的任一个
ScriptEngine engine = manager.getEngineByName("javascript");
脚本引擎除了简单的执行功能,还可以通过它向脚本中传递参数,同时也可以将脚本中的变量值取出来。这些功能要依靠ScriptEngine#put()
和ScriptEngine#get()
方法,以下为代码示例
public static void main(String[] args) {ScriptEngineManager manager = new ScriptEngineManager();
// 获取javascript脚本引擎
ScriptEngine engine = manager.getEngineByName("js");
try {// 参数出入
engine.put("name", "lucky");
// 开始执行脚本
engine.eval("var output ='' ;" +
"for (i = 0; i<= name.length; i++) {" +
" output = name.charAt(i) + output" +
"}");
// 得到output变量的值
String name = (String) engine.get("output");
System.out.printf("被翻转后的字符串:%s", name);
} catch (Exception e) {System.err.println(e);
}
}
2.2 脚本编译如我们所知,脚本解释执行的运行方式性能很低,但是不少脚本语言都支持编译功能,因此 Java 的脚本引擎也对编译进行了支持。如果某段脚本要运行多次的话,可以使用编译的方式将其转化为执行效率更高的形式,从而提高性能
具体做法是调用ScriptEngine#compile()
方法进行脚本编译,不过只有实现了Compilable
接口的脚本引擎才可以进行编译,可参考以下示例
public static void main(String[] args) {ScriptEngineManager manager = new ScriptEngineManager();
// 得到javascript脚本引擎
ScriptEngine engine = manager.getEngineByName("js");
try {// 可编译的脚本,提高执行速度
engine.put("counter", 0);
// 判断这个脚本引擎是否支持编译功能
if (engine instanceof Compilable) {Compilable compEngine = (Compilable) engine;
CompiledScript script = compEngine.compile("function count() { " +
" counter = counter +1; " +
" return counter; " +
"};" +
"count();");
System.out.printf("Counter: %s%n", script.eval());
System.out.printf("Counter: %s%n", script.eval());
System.out.printf("Counter: %s%n", script.eval());
}
} catch (Exception e) {System.err.println(e);
}
}
2.3 脚本动态调用业务系统运行时通常需要将用户的输入作为入参执行函数,这就产生了脚本方法动态调用的需求。和编译一样,脚本引擎必须实现Invocable
接口才可以动态调用脚本中的方法,具体可参考以下示例
public static void main(String[] args) {ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
try {// 动态决定脚本调用
String name = "nathan";
if (engine instanceof Invocable) {engine.eval("function reverse(name) {" +
" var output =' ';" +
" for (i = 0; i<= name.length; i++) {" +
" output = name.charAt(i) + output" +
" }" +
" return output;" +
"}");
Invocable invokeEngine = (Invocable) engine;
Object o = invokeEngine.invokeFunction("reverse", name);
System.out.printf("翻转后的字符串:%s", o);
}
} catch (Exception e) {System.err.println(e);
}
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧