2.1 脚本语言支持API
随着Java平台的流行,很多脚本语言(scripting language)都可以运行在Java虚拟机上,其中比较流行的有JavaScript、JRuby、Jython和Groovy等。相对Java语言来说,脚本语言由于其灵活性很强,非常适合在某些情况下使用,比如描述应用中复杂多变的业务逻辑,并在应用运行过程中进行动态修改;为应用提供一种领域特定语言(Domain-specific Language, DSL),供没有技术背景的普通用户使用;作为应用中各个组件之间的“胶水”,快速进行组件之间的整合;快速开发出应用的原型系统,从而迅速获取用户反馈,并进行改进;帮助开发人员快速编写测试用例等。对于这些场景,如果使用Java来开发,会事倍功半。
对于这些运行在Java虚拟机平台上的脚本语言来说,并不需要为它们准备额外的运行环境,直接复用已有的Java虚拟机环境即可。这就节省了在运行环境上所需的成本投入。在应用开发中使用脚本语言,实际上是“多语言开发”的一种很好的实践,即根据应用的需求和语言本身的特性来选择最合适的编程语言,以快速高效地解决应用中的某一部分问题。多种不同语言实现的组件结合起来,就形成了最终的完整应用程序。比如一个应用,可以用Groovy来编写用户界面,用Java编写核心业务逻辑,用Ruby来进行数据处理。不同语言编写的代码可以同时运行在同一个Java虚拟机之上。这些脚本语言与Java语言之间的交互,是由脚本语言支持API来完成的。
JSR 223(Scripting for the JavaTMPlatform)中规范了在Java虚拟机上运行的脚本语言与Java程序之间的交互方式。JSR 223是Java SE 6的一部分,在Java标准API中的包是javax.script。下面将详细介绍与脚本语言支持API相关的内容。
2.1.1 脚本引擎
一段脚本的执行需要由该脚本语言对应的脚本引擎来完成。一个Java程序可以选择同时包含多种脚本语言的执行引擎,这完全由程序的需求来决定。程序中所用到的脚本语言,都需要有相应的脚本引擎。JSR 223中定义了脚本引擎的注册和查找机制。这对于脚本引擎的实现者来说是需要了解的。而一般的开发人员只需要了解如何通过脚本引擎管理器来获取对应语言的脚本引擎即可,并不需要了解脚本引擎的注册机制。Java SE 6中自带了JavaScript语言的脚本引擎,是基于Mozilla的Rhino来实现的。对于其他的脚本语言,则需要下载对应的脚本引擎的库并放到程序的类路径中。一般只要放在类路径中,脚本引擎就可以被应用程序发现并使用。
首先介绍脚本引擎的一般用法。在代码清单2-1中,首先创建一个脚本引擎管理器javax.script.ScriptEngineManager对象,再通过管理器来查找所需的JavaScript脚本引擎,最后通过脚本引擎来执行JavaScript代码。示例中的JavaScript代码做的事情很简单,只输出了字符串“Hello!”。JavaScript代码中的println是Rhino引擎额外提供的方法,相当于Java中的System.out.println方法。
代码清单2-1 脚本引擎的一般用法
public void greet()throws ScriptException{
ScriptEngineManager manager=new ScriptEngineManager();
ScriptEngine engine=manager.getEngineByName("JavaScript");
if(engine==null){
throw new RuntimeException("找不到JavaScript语言执行引擎。");
}
engine.eval("println('Hello!');");
}
上面的代码中是通过脚本引擎的名称进行查找的。实际上,脚本引擎管理器共支持三种查找脚本引擎的方式,分别通过名称、文件扩展名和MIME类型来完成。比如对于同样的JavaScript语言引擎,还可以通过getEngineByExtension("js")和getEngineByMimeType("text/javascript")来查找到。得到脚本引擎ScriptEngine的对象之后,通过其eval方法可以执行一段代码,并返回这段代码的执行结果。这是最基本的通过脚本引擎来解释执行一段脚本的实现方式。