一: 简介<o:p></o:p>
JDK1.6加入了对Script(JSR223)的支持,使Host Application有能力执行Script。这将带来如下便利:
(1) 对程序的定制更加容易灵活:您可以将很容易变化的算法如企业促销返利算法等写到script中
(2) 可以使用您喜爱的script语言完成任务(如Prototype,生成web页面等),同时可以利用强大的Java平台资源
(3) 您的JavaScript可以进行JUnit测试了
二: Script Engine发现机制
Main.java
- package com.rainsoft.execise.script;
-
- import javax.script.*;
- import java.util.List;
-
-
-
-
-
-
- public class Main {
- public static void main(String[] args) {
- ScriptEngineManager mgr = new ScriptEngineManager();
- List
<scriptenginefactory></scriptenginefactory>
factorys = mgr.getEngineFactories();
- for (ScriptEngineFactory factory : factorys) {
- String name = factory.getEngineName();
- String version = factory.getEngineVersion();
- String langName = factory.getLanguageName();
- String langVer = factory.getLanguageVersion();
-
- System.out.printf("Engine:%s(%s), Language:%s(%s)\n",
- name, version, langName, langVer);
- }
- }
- }
运行结果:
- Engine:Mozilla Rhino(1.6 release 2), Language:ECMAScript(1.6)
ScriptEngineManager使用service provider mechanism来实现ScriptEngine的发现.
Sun JDK1.6自带Rhino Javascript Engine,其service描述文件在resources.jar的/META-INF/services/ javax.script.ScriptEngineFactory中,内容为:
resources.jar的/META-INF/services/ javax.script.ScriptEngineFactory文件内容:
- #script engines supported
- com.sun.script.javascript.RhinoScriptEngineFactory #javascript
三: 使用ScriptEngine使程式定制更容易
您已经可以用properties档或xml档configure您的程式,但对于经常变化的算法而言却是不易,有了Script Support,这就容易多了。
比如您为客户开发计算个税的程式,在国家计税方法变化时,您固然可以modify java src, compile, test, deploy完成,但如果仅仅改一下configure档就能搞定也许让人更愉快 :-)
让我们用代码说明:
TaxCalculator.java
- package com.rainsoft.execise.script;
-
- import javax.script.*;
- import java.io.FileReader;
- import java.io.FileNotFoundException;
- import org.apache.log4j.Logger;
-
- public class TaxCalculator {
- Logger logger = Logger.getLogger(TaxCalculator.class);
-
-
- private static final String TAX_CALCULATOR_JS = "TaxCalculator.js";
- private static final String SCRIPT_NAME = "ECMAScript";
- private static final String FUNC_CAL_PERSONAL_TAX = "calPersonalTax";
-
-
- private ScriptEngine engine = null;
- private Invocable invocableEngine = null;
-
-
-
-
- public TaxCalculator() throws FileNotFoundException, ScriptException {
- ScriptEngineManager engineMgr = new ScriptEngineManager();
- engine = engineMgr.getEngineByName(SCRIPT_NAME);
- if (engine == null) {
- throw new ScriptException("Can not initialize ECMAScript engine!");
- }
-
- Object ret = engine.eval(new FileReader(TAX_CALCULATOR_JS));
- if (ret != null && logger.isDebugEnabled()) {
- logger.debug("Following is returned by eval " + TAX_CALCULATOR_JS);
- logger.debug(ret.toString());
- }
-
- if (!(engine instanceof Invocable)) {
- throw new ScriptException("Engine does not support Invocable interface!");
- }
- invocableEngine = (Invocable)engine;
- }
-
-
-
-
- public double calPersonalIncomeTax(Employee emp)
- throws NoSuchMethodException, ScriptException {
- Object ret = invocableEngine.invokeFunction(FUNC_CAL_PERSONAL_TAX, emp);
-
- assert(ret instanceof Double);
- return (Double)ret;
- }
- }
(1) Constructor完成初始化JS引擎的工作
(2) calPersonalIncomeTax完成计算个税工作,方法体仅仅调用js脚本中的相关(同名)function
(3) 代码品质可以进一步提高:实现为Singleton; 将部分const放到properties档中。至于并发,让engine自己管理好了[1]
(4) 程式通过传参让js知晓emp的存在,对于更适合让js当作内建对象的Object来说,可以用如下代码做到
- engine.getContext().setAttribute("BuildinObject", anInstance, ScriptContext.ENGINE_SCOPE);
TaxCalculator.js
-
- function calPersonalTax(emp) {
- taxSalary = emp.salary - emp.the4Money - 1600;
-
- taxRate = 0;
- if (taxSalary > 0 && taxSalary <= 500) {
- taxRate = 0.05;
- }
- else if (taxSalary > 500 && taxSalary <= 2000) {
- taxRate = 0.1;
- }
- else {
- taxRate = 0.15; // just demo
- }
-
- return taxSalary * taxRate;
- }
简单测试一下:
- public static void main(String[] args) throws Exception {
- Employee emp = new Employee(1, 8000, 900);
- double tax = new TaxCalculator().calPersonalIncomeTax(emp);
- System.out.printf("Tax:%.0f", tax);
- }
结果:
Oh,yeah!
四:附录
[1] JSR223 P135: Scripts are executed synchronously. There is no mechanism defined in this specification to execute them asynchronously or to interrupt script execution from another thread. These must be implemented at application level.
五:修订历史
2006-12-12 增加"一:简介"第三条,谢谢网友"抛出异常的爱"的贡献
- src.rar (2 KB)
- 描述: 本文的源程序,JDK6下通过.
- 下载次数: 229
分享到:
- 2006-12-08 17:05
- 浏览 7669
- 评论(9)
- 论坛回复 / 浏览 (9 / 13263)
- 查看更多
相关推荐
jdk1.6+1.8.zip
MacOS下jdk1.6+Eclipse4.4.2+JBoss4.2.2+SVN开发环境搭建
tomcat7-jdk1.6+redis session共享所有依赖包: tomcat-redis-session-manager.jar jedis.jar commons-pool.jar 以及Tomcat对应的配置示例,亲测可用
自己写的一个文件名批量转换工具,使用率应该不高,但是有时候可能还是会用到,JDK1.6+ 可以转换文件夹里所有后缀名相同的文件转换成另一后缀 自己用的
Ubuntu下配置java环境(JDK1.6+eclipse+myeclipse+tomcat)
本教程介绍了"jdk1.6+MyEclipse6.5+Tomcat 6.0" 的开发环境的搭建设和配置,针对关键的每一步都进行了说明,另附截图,对新人来说比较容易理解和上手. 让新人少走弯路,对老鸟和大虾来说,就不用看了.
Red Hat Linux9.0下tomcat6+jdk1.6+oracle9i安装宝典。oracle9i的安装参考本人发的另一篇Red Hat Linux9.0下Oracle9i安装详解。
jdk1.6+tomcat7.0.90 jdk需要安装 tomcat解压即用
本人自己根据“精通struts”上的例子写的一个helloworld例子,已经调试通过,希望对大家有帮助。jdk1.6+Tomcat6.0+eclipse3.5+struts1.3.10
linux+jdk1.6+oracle+websphere安装部署,工程发布 linux as5 jdk1.6 oracle 10g websphere v7试用版 经过本人亲自安装测试。
JDK1.6 + Tomcat6.0 + MyEclipse7.5 + Oracle XE(10g)
CentOS中架设jdk1.6+mysql+glassfishV3(tomcat6).pdf
1、适用需要特定版本jdk的 2、适用维护旧项目安全漏洞升级的 3、适用入门不知用何版本的小白 4、适用64位Linux,解压即可用,1.6版本的为可执行文件,安装即用。
Jdk+api+1.6+英文原版 CHM格式
手册记录的非常详细包括jdk1.6,tomcat6.0,mysql5.1,mysql驱动的安装与配置,在myeclipse下部署及运行 示例
JDK+1.6+API中文版
适合okhttp,okio JDK1.6:okhttp3.8.0-jdk1.6.jar JDK1.6+:okhttp-3.12.13.jar;okio-1.15.0.jar 适用于Java开发环境、使用OkHttp调用
本文档详细讲解了如何配置jdk 、tomcat 、myeclipse ,非常适合java的新手们学习
mac for jdk1.6 jdk6 安装版 里面有两个jdk1.6的安装包,都可以用 如果电脑上安装有1.7,1.8等高版本jdk就不要再下安装包了,安装包安装会报错 命令是这个:brew install java6或 brew install homebrew/cask-...
JDK1.6,JDK1.8 Windows安装包。