Java 脚本化编程指南.docx

上传人:b****5 文档编号:6608868 上传时间:2023-01-08 格式:DOCX 页数:12 大小:21.59KB
下载 相关 举报
Java 脚本化编程指南.docx_第1页
第1页 / 共12页
Java 脚本化编程指南.docx_第2页
第2页 / 共12页
Java 脚本化编程指南.docx_第3页
第3页 / 共12页
Java 脚本化编程指南.docx_第4页
第4页 / 共12页
Java 脚本化编程指南.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

Java 脚本化编程指南.docx

《Java 脚本化编程指南.docx》由会员分享,可在线阅读,更多相关《Java 脚本化编程指南.docx(12页珍藏版)》请在冰豆网上搜索。

Java 脚本化编程指南.docx

Java脚本化编程指南

Java脚本化编程指南

Java脚本化API为谁准备?

脚本语言的一些有用的特性是:

∙方便:

大多数脚本语言都是动态类型的。

您通常可以创建新的变量,而不声明变量类型,并且您可以重用变量来存储不同类型的对象。

此外,脚本语言往往会自动执行许多类型的转换,例如,必要时将数字10转换为“10”。

∙开发快速原型:

您可以避免编辑编译运行周期,只使用“编辑运行”!

∙应用扩展/定制:

你可以“具体化”的部分应用程序,例如一些配置脚本,业务逻辑/规则和财务应用中的数学表达式。

∙为应用添加命令行模式,用于调试、运行时配置/部署时间。

现在大多数应用程序都有一个基于Web的GUI配置工具。

但是系统管理员/部署人员常常喜欢命令行工具。

一个“标准”的脚本语言可以用来实现这个目的,而不是发明特设的脚本语言。

Java脚本API是一种独立于框架的脚本语言,使用来自于Java代码的脚本引擎。

通过java脚本API,可以使用Java语言编写定制/可扩展的应用程序并将自定义脚本语言选择留给最终用户。

Java应用程序开发者不需要在开发过程中选择扩展语言。

如果你使用JSR-223API来编写应用,那么你的用户可以使用任何JSR-223兼容的脚本语言。

脚本包

Java脚本功能是在javax.script包中。

这是一个比较小的,简单的API。

脚本的出发点是ScriptEngineManager类。

一个ScriptEngineManager对象可以通过jar文件的服务发现机制发现脚本引擎。

它也可以实例化脚本引擎来解释使用特定的脚本语言编写的脚本。

使用脚本编程接口的最简单的方法如下:

1.创建一个 ScriptEngineManager 对象

2.从 ScriptEngineManager 获取 ScriptEngine 对象

3.使用 ScriptEngine的eval方法执行脚本

现在,是时候看一些样本代码了。

了解一些JavaScript有助于阅读这些例子,但不是强制的。

实例

“Hello,World”

从ScriptEngineManager实例中,我们通过 getEngineByName 方法得到一个JavaScript引擎实例。

通过脚本引擎的eval方法来执行给定的JavaScript代码。

为简便起见,本例以及随后的例子中,我们不对异常进行处理。

javax.scriptAPI有检查和运行时异常,你必须妥善处理异常。

1

2

3

4

5

6

7

8

9

10

11

importjavax.script.*;

publicclassEvalScript{

    publicstaticvoidmain(String[]args)throwsException{

        //createascriptenginemanager

        ScriptEngineManagerfactory=newScriptEngineManager();

        //createaJavaScriptengine

        ScriptEngineengine=factory.getEngineByName("JavaScript");

        //evaluateJavaScriptcodefromString

        engine.eval("print('Hello,World')");

    }

}

执行一个脚本文件

在这个例子中,我们调用eval方法来接收java.io.Reader作为输入源。

读入的脚本被执行。

这种方式能够成文件执行脚本,用相关的输入流对象读取URL和资源。

1

2

3

4

5

6

7

8

9

10

11

importjavax.script.*;

publicclassEvalFile{

    publicstaticvoidmain(String[]args)throwsException{

        //createascriptenginemanager

        ScriptEngineManagerfactory=newScriptEngineManager();

        //createJavaScriptengine

        ScriptEngineengine=factory.getEngineByName("JavaScript");

        //evaluateJavaScriptcodefromgivenfile-specifiedbyfirstargument

        engine.eval(newjava.io.FileReader(args[0]));

    }

}

假设我们有一个叫”test.js”的文件,里面的内容如下:

1

println("Thisishellofromtest.js");

我们可以使用下面的方式来运行刚刚的脚本

1

javaEvalFiletest.js

脚本变量

当你的java应用程序嵌入脚本引擎和脚本,你可能希望将您的应用程序对象为全局变量暴露于脚本中。

这个例子演示了如何将您的应用程序对象作为全局变量暴露于脚本中。

我们在应用程序中创建一个 java.io.File对象作为全局变量,名称是file。

该脚本可以访问变量,例如,它可以调用它的公共方法。

注意访问java对象、领域和方法的语法依赖于脚本语言。

JavaScript支持最“自然”的类似java的语法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

publicclassScriptVars{

    publicstaticvoidmain(String[]args)throwsException{

        ScriptEngineManagermanager=newScriptEngineManager();

        ScriptEngineengine=manager.getEngineByName("JavaScript");

 

        Filef=newFile("test.txt");

        //exposeFileobjectasvariabletoscript

        engine.put("file",f);

 

        //evaluateascriptstring.Thescriptaccesses"file"

        //variableandcallsmethodonit

        engine.eval("print(file.getAbsolutePath())");

    }

}

调用脚本函数和方法

有些时候,你可能需要多次调用一个特定脚本函数,例如你的应用程序菜单功能可能由脚本来实现。

在菜单中的操作事件处理程序中,可能需要调用一个特定的脚本函数。

下面的示例演示在Java代码调用一个特定的脚本。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

importjavax.script.*;

 

publicclassInvokeScriptFunction{

    publicstaticvoidmain(String[]args)throwsException{

        ScriptEngineManagermanager=newScriptEngineManager();

        ScriptEngineengine=manager.getEngineByName("JavaScript");

 

        //JavaScriptcodeinaString

        Stringscript="functionhello(name){print('Hello,'+name);}";

        //evaluatescript

        engine.eval(script);

 

        //javax.script.Invocableisanoptionalinterface.

        //Checkwhetheryourscriptengineimplementsornot!

        //NotethattheJavaScriptengineimplementsInvocableinterface.

        Invocableinv=(Invocable)engine;

 

        //invoketheglobalfunctionnamed"hello"

        inv.invokeFunction("hello","Scripting!

!

");

    }

}

如果你的脚本语言是基于对象(如JavaScript)或面向对象的,你可以在脚本对象上调用脚本方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

importjavax.script.*;

 

publicclassInvokeScriptMethod{

 publicstaticvoidmain(String[]args)throwsException{

   ScriptEngineManagermanager=newScriptEngineManager();

   ScriptEngineengine=manager.getEngineByName("JavaScript");

 

  //JavaScriptcodeinaString.Thiscodedefinesascriptobject'obj'

   //withonemethodcalled'hello'.

   Stringscript="varobj=newObject();obj.hello=function(name){print('Hello,'+name);}";

   //evaluatescript

   engine.eval(script);

 

   //javax.script.Invocableisanoptionalinterface.

   //Checkwhetheryourscriptengineimplementsornot!

   //NotethattheJavaScriptengineimplementsInvocableinterface.

   Invocableinv=(Invocable)engine;

 

   //getscriptobjectonwhichwewanttocallthemethod

   Objectobj=engine.get("obj");

 

   //invokethemethodnamed"hello"onthescriptobject"obj"

   inv.invokeMethod(obj,"hello","ScriptMethod!

!

");

 }

}

通过脚本实现Java接口

有些时候通过脚本函数或者方法可以很方便的实现java接口,而不是在Java中调用。

同时,通过接口我们可以避免在很多地方使用javax.scriptAPI接口。

我们可以得到一个接口实现者对象并将其传递给不同的Javaapi。

下面的例子演示了通过脚本实现java.lang.Runnable接口。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

importjavax.script.*;

 

publicclassRunnableImpl{

    publicstaticvoidmain(String[]args)throwsException{

        ScriptEngineManagermanager=newScriptEngineManager();

        ScriptEngineengine=manager.getEngineByName("JavaScript");

 

        //JavaScriptcodeinaString

        Stringscript="functionrun(){println('runcalled');}";

 

        //evaluatescript

        engine.eval(script);

 

        Invocableinv=(Invocable)engine;

 

        //getRunnableinterfaceobjectfromengine.Thisinterfacemethods

        //areimplementedbyscriptfunctionswiththematchingname.

        Runnabler=inv.getInterface(Runnable.class);

 

        //startanewthreadthatrunsthescriptimplemented

        //runnableinterface

        Threadth=newThread(r);

        th.start();

    }

}

如果你的脚本语言是基于对象或者面向对象的,可以通过脚本对象的脚本方法来实现Java接口。

这避免了不得不调用脚本全局函数的接口方法。

脚本对象可以存储接口实现状态。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

importjavax.script.*;

 

publicclassRunnableImplObject{

    publicstaticvoidmain(String[]args)throwsException{

        ScriptEngineManagermanager=newScriptEngineManager();

        ScriptEngineengine=manager.getEngineByName("JavaScript");

 

        //JavaScriptcodeinaString

        Stringscript="varobj=newObject();obj.run=function(){println('runmethodcalled');}";

 

        //evaluatescript

        engine.eval(script);

 

        //getscriptobjectonwhichwewanttoimplementtheinterfacewith

        Objectobj=engine.get("obj");

 

        Invocableinv=(Invocable)engine;

 

        //getRunnableinterfaceobjectfromengine.Thisinterfacemethods

        //areimplementedbyscriptmethodsofobject'obj'

        Runnabler=inv.getInterface(obj,Runnable.class);

 

        //startanewthreadthatrunsthescriptimplemented

        //runnableinterface

        Threadth=newThread(r);

        th.start();

    }

}

脚本的多作用域

我们看到怎样将应用对象暴露为脚本的全局变量。

它有可能暴露为多个全局的作用域 。

单作用域是javax.script.Bindings的实例中.这个借口派生至java.util.Map

 scope键值对的集合,其中键为非空、非空字符串。

 多scopes是 javax.script.ScriptContext 接口支持的。

支持一个或多个脚本上下文与相关的域绑定。

默认情况下,每一个脚本引擎都有一个默认的脚本上下文。

 默认的脚本上下文有至少一个域叫 ”ENGINE_SCOPE”。

不同域的脚本上下文支持可以通过 getscopes 方法获取。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

importjavax.script.*;

 

publicclassMultiScopes{

    publicstaticvoidmain(String[]args)throwsException{

        ScriptEngineManagermanager=newScriptEngineManager();

        ScriptEngineengine=manager.getEngineByName("JavaScript");

 

        engine.put("x","hello");

        //printglobalvariable"x"

        engine.eval("println(x);");

        //theabovelineprints"hello"

 

        //Now,passadifferentscriptcontext

        ScriptContextnewContext=newSimpleScriptContext();

        BindingsengineScope=newContext.getBindings(ScriptContext.ENGINE_SCOPE);

 

        //addnewvariable"x"tothenewengineScope       

        engineScope.put("x","world");

 

        //executethesamescript-butthistimepassadifferentscriptcontext

        engine.eval("println(x);",newContext);

        //theabovelineprints"world"

    }

}

JavaScript脚本引擎

Sun的JDK6中包含了一个基于 MozillaRhino JavaScript脚本引擎。

 这个引擎是基于版本为1.6R2的MozillaRhino。

多数 Rhino实现都被包含在内。

少部分组件由于大小和安全原因被排除了:

1.JavaScript转字节码编译 (也称 ”优化器”).。

此功能依赖一个类生成库。

 去掉本功能意味着:

JavaScript是解释执行,且不影响脚本执行,因为优化器是透明的。

2.Rhino的JavaAdapter也被去掉了。

 JavaAdapter是一个JavaScript可扩展Java类和JavaScript可实现Java接口功能。

此功能也是需要类生成库的。

我们把Rhino的JavaAdapter替换为Sun实现的JavaAdapter。

在Sun的实现中,仅仅实现了JavaScript对象可实现Java单接口功能。

例如,下面的代码会正确执行。

1

2

3

4

varv=newjava.lang.Runnable(){

                    run:

function(){print('hello');}

               }

v.run();

3.在大多数情况下,JavaAdapter是采用匿名类语法来实现单接口。

使用JavaAdapter来扩展Java类或实现多接口并不常见。

4.E4X(ECMAScriptforXML–ECMAStandard357)被去掉了.使用XMLJavaScript代码会产生一个语法错误.请注意,E4X支持ECMAScript标准是可选的-省略E4X的实现是被支持也是兼容ECMAScript。

5.Rhino的命令行工具 (Rhinoshell,debugger等)没有被包含在内。

但你可以用使用 jrunscript来代替。

JavaScript与Java的通信

在大多数情况下,访问Java类、对象和方法很简单。

从JavaScript中访问属性和方法与同Java中一样。

下面是一些JavaScript访问Java的代码片段。

本节需要一些JavaScript知识。

如果你打算使用JSR-223中非JavaScript脚本语言,那么本节可以跳过。

引入Java包,类

内置的函数importPackage 和importClass 可以用于引入Java包和类。

1

2

3

4

5

6

7

8

9

10

11

//ImportJavapackagesandclasses

//likeimportpackage.*;inJava

importPacka

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1