日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 脚本语言交互_Java学习笔记--脚本语言支持API

發(fā)布時(shí)間:2023/12/15 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 脚本语言交互_Java学习笔记--脚本语言支持API 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java語言的動(dòng)態(tài)性之腳本語言支持API

隨著Java平臺(tái)的流行,很多的腳本語言(scripting language)都可以運(yùn)行在Java虛擬機(jī)啊上,其中比較流行的有JavaScript、JRuby、Jython和Groovy等。相對(duì)Java語言來說,腳本語言由于其靈活性非常強(qiáng),非常適合在某些情況下使用,比如描述應(yīng)用中復(fù)雜多變的業(yè)務(wù)邏輯,并在應(yīng)用運(yùn)行過程中進(jìn)行動(dòng)態(tài)修改;為應(yīng)用提供一種領(lǐng)域特定語言(Domainspecific Language,DSL),供沒有技術(shù)背景的普通用戶使用;作為應(yīng)用中各個(gè)組件之間的“膠水”,快速進(jìn)行組件之間的整合;快速開發(fā)出應(yīng)用的原型系統(tǒng),從而迅速獲取用戶反饋,并進(jìn)行改進(jìn);幫助開發(fā)人員快速編寫測(cè)試用例等。等于這些場(chǎng)景,如果使用java來開發(fā)則事倍功半。

對(duì)于這些運(yùn)行在Java虛擬機(jī)平臺(tái)上的腳本語言來說,并不需要為她們準(zhǔn)備額外的運(yùn)行環(huán)境,直接復(fù)用已有的Java虛擬機(jī)環(huán)境即可。這就節(jié)省了在運(yùn)行環(huán)境上所需的成本投入。在應(yīng)用開發(fā)中使用腳本語言,實(shí)際上是“多語言開發(fā)”的一種很好的實(shí)踐,即根據(jù)應(yīng)用的需要和語言本身的特性來選擇最合適的變成語言,以快速高效地解決應(yīng)用中的某一部分問題。多種不同語言實(shí)現(xiàn)的組件組合起來,用Java編寫核心業(yè)務(wù)邏輯,用Ruby來進(jìn)行數(shù)據(jù)處理。不同語言編寫的代碼可以同時(shí)運(yùn)行的同一個(gè)Java虛擬機(jī)之上。這些腳本語言和Java語言之間的交互,是由腳本語言支持API來完成的。

1.腳本引擎

一段腳本的執(zhí)行需要由該腳本語言對(duì)應(yīng)的腳本引擎來完成。一個(gè)Java程序可以選擇同時(shí)包含多種腳本語言的執(zhí)行引擎,這完全由程序的需求來決定。程序中所用到的腳本語言,都需要有相應(yīng)的腳本引擎。JSR 233中定義了腳本引擎的注冊(cè)和查找機(jī)制。這對(duì)于腳本引擎的實(shí)現(xiàn)者來說,是需要了解的。而一般的開發(fā)人員只需要了解如何通過腳本引擎管理器來獲取對(duì)應(yīng)語言的腳本引擎,并不需要了解腳本引擎的注冊(cè)機(jī)制。Java SE6中自帶了JavaScript語言的腳本引擎,是基于Mozilla的Rhino來實(shí)現(xiàn)的。對(duì)于其他的腳本語言,則需要下載對(duì)應(yīng)的腳本引擎的庫并放在程序的類路徑中。一般只要放在類路徑中中,腳本引擎就可以被應(yīng)用程序發(fā)現(xiàn)并使用。

首先介紹腳本引擎的一般用法。首先創(chuàng)建一個(gè)腳本引擎管理器javax.script.ScriptEngineManager對(duì)象,再通過管理器來查詢所需的JavaScript腳本引擎,最后通過腳本引擎來執(zhí)行JavaScript代碼。

ScriptEngineManagerDemo

執(zhí)行結(jié)果

上面的代碼中是通過腳本引擎的名字進(jìn)行查找的。實(shí)際上,腳本引擎管理共支持三種查找腳本引擎的方式,分別通過名稱、文件擴(kuò)展名和MIME類型來完成。

2.語言綁定

腳本語言支持API的一個(gè)很大優(yōu)勢(shì)在于它規(guī)范了Java語言與腳本語言之間的交互方式,使Java語言編寫的程序可以與腳本之間進(jìn)行雙向的方法調(diào)用和數(shù)據(jù)傳遞。方法調(diào)用的方式會(huì)在稍后介紹。數(shù)據(jù)傳遞是通過語言綁定對(duì)象來完成的。所謂的綁定對(duì)象就是一個(gè)簡(jiǎn)單的哈希表,用來存放和獲取需要共享的數(shù)據(jù)。所有數(shù)據(jù)都對(duì)應(yīng)這個(gè)哈希表中的一個(gè)條目,是簡(jiǎn)單的名值對(duì)。接口javax.script.Bindings定義了語言綁定對(duì)象的接口,繼承自java.util.Map接口。一個(gè)腳本引擎在執(zhí)行過程中可能會(huì)使用多個(gè)語言綁定對(duì)象。不同語言綁定對(duì)象的作用域不同。在默認(rèn)情況下,腳本引擎會(huì)提供多個(gè)語言綁定對(duì)象,用來存放在執(zhí)行過程中產(chǎn)生全局對(duì)象等。ScriptEngine類提供了put和get方法對(duì)腳本引擎中特定作用域的默認(rèn)語言綁定對(duì)象進(jìn)行操作。程序可以直接使用這個(gè)默認(rèn)的語言綁定對(duì)象,也可以使用自己的語言綁定對(duì)象。在腳本語言的執(zhí)行過程中,可以將語言綁定對(duì)象看成是一個(gè)額外的變量映射表。在解析變量值的時(shí)候,語言綁定對(duì)象中的名稱也會(huì)被考慮在內(nèi)。腳本執(zhí)行過程中產(chǎn)生的全局變量等內(nèi)容,會(huì)出現(xiàn)在語言綁定對(duì)象中。通過這種方式就完成了Java與腳本語言之間的雙向數(shù)據(jù)傳遞。

腳本引擎默認(rèn)的語言綁定對(duì)象的示例

/**

* 腳本引擎默認(rèn)的語言綁定對(duì)象的示例

*/

public static void useDefaultBinding(){

try{

ScriptEngine engine = getJavaScriptEngine();

engine.put("name","Arthur");

engine.eval("var message = 'Hello,' + name;");

engine.eval("print(message);");

Object obj = engine.get("message");

System.out.println(obj);

}catch (Exception e){

System.out.println("異常信息:"+e.getMessage());

}

}

腳本引擎默認(rèn)的語言綁定對(duì)象的示例執(zhí)行結(jié)果

在大多數(shù)情況下,使用ScriptEngine的put和get方法就足夠了。如果僅使用put和get方法,語言綁定對(duì)象本身對(duì)于開發(fā)人員來說是透明的。在某些情況下,需要使用程序自己的語言綁定對(duì)象,比如語言綁定對(duì)象中包含了程序自己獨(dú)有的數(shù)據(jù)。如果希望使用自己的語言綁定對(duì)象,可以調(diào)用腳本引擎的createBindings方法或創(chuàng)建,并傳遞給腳本引擎的eval方法。

自定義語言綁定對(duì)象的示例

/**

* 自定義語言綁定對(duì)象的示例

*/

public static void userCustomBinding(){

try{

ScriptEngine engine = getJavaScriptEngine();

Bindings bindings = new SimpleBindings();

bindings.put("hobby","playe games");

engine.eval("print('I like ' + hobby);",bindings);

}catch(Exception e){

System.out.println("異常信息:"+e.getMessage());

}

}

自定義語言綁定對(duì)象的示例的執(zhí)行結(jié)果

通過eval方法傳遞的語綁定對(duì)象,僅在當(dāng)前eval調(diào)用中生效,并不會(huì)改變引擎默認(rèn)的語言綁定對(duì)象。

3.腳本執(zhí)行上下文

與腳本引擎執(zhí)行相關(guān)的另外一個(gè)重要的接口是javax.script.ScriptContext,其中包含腳本引擎執(zhí)行過程的相關(guān)上下文信息,可以通過與Java EE中servlet規(guī)范中的javax.servlet.ServletContext接口來進(jìn)行類比。腳本引擎通過此上下文對(duì)象獲取與腳本執(zhí)行相關(guān)的信息,也允許開發(fā)人員通過此對(duì)象來配置腳本引擎的行為。該上下文對(duì)象主要包含以下3類信息:

3.1輸入與輸出

首先介紹與腳本輸入和輸出的配置信息,其中包括腳本在執(zhí)行中用來讀取數(shù)據(jù)輸入的java.io.Reader對(duì)象以及輸出正確內(nèi)容和出錯(cuò)信息的java.io.Writer對(duì)象。在默認(rèn)情況下,腳本的輸入輸出都在發(fā)生在標(biāo)準(zhǔn)控制臺(tái)中。

把腳本運(yùn)行時(shí)的輸出寫入到文件中的示例

/**

* 把腳本運(yùn)行時(shí)的輸出寫入到文件中。

*/

public static void scriptToFile(){

try {

ScriptEngine engine = getJavaScriptEngine();

ScriptContext context = engine.getContext();

context.setWriter(new FileWriter("output.txt"));

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

} catch (ScriptException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

執(zhí)行結(jié)果

說明

通過setWriter方法把腳本的輸出重定向到一個(gè)文件中。通過ScriptContext的setReader和setErrorWriter方法可以分別設(shè)置腳本執(zhí)行時(shí)的數(shù)據(jù)輸入來源和產(chǎn)生錯(cuò)誤時(shí)出錯(cuò)信息的輸出目的。

3.2自定義屬性

ScriptContext中也有與ServletConext中類似的獲取和設(shè)置屬性的方法,即setAttribute和getAttribute。所不同的是,ScriptContext中的屬性是有作用域之分的。不同作用域的區(qū)別在于查找屬性時(shí)的順序不同。每個(gè)作用域都以一個(gè)對(duì)應(yīng)的整數(shù)表示其查找順序。該整數(shù)值越小,說明查找時(shí)的順序越優(yōu)先。優(yōu)先級(jí)高的作用域中的屬性會(huì)隱藏優(yōu)先級(jí)低的作用域中的同名屬性。因此,設(shè)置屬性時(shí)需要顯式地指定所在地作用域。在獲取屬性地時(shí)候,既可以選擇在指定地作用域中查找,也可以選擇根據(jù)作用域優(yōu)先級(jí)自動(dòng)進(jìn)行查找。

不過腳本執(zhí)行上下文實(shí)現(xiàn)中包含地作用域是固定的,開發(fā)人員不能隨意定義自己的作用域。通過ScriptContext的getScopes方法可以得到所有可用的作用域列表。ScriptContext中預(yù)先定義了兩個(gè)作用域:

常量ScriptContext.ENGINE_SCOPE表示的作用域?qū)?yīng)的是當(dāng)前的腳本引擎。

常量ScriptContext.GLOBAL_SCOPE表示的作用域?qū)?yīng)的是從同一引擎工廠中創(chuàng)建出來的所有腳本引擎對(duì)象。

說明: 前者的優(yōu)先級(jí)較高

作用域影響同名屬性查找示例

/**

* 作用域影響同名屬性查找的示例

*/

public static void scriptContextAttribute(){

try{

ScriptEngine engine = getJavaScriptEngine();

ScriptContext context = engine.getContext();

context.setAttribute("name","Arthur Ming",ScriptContext.GLOBAL_SCOPE);

context.setAttribute("name","明國賓",ScriptContext.ENGINE_SCOPE);

System.out.println(context.getAttribute("name"));

System.out.println(context.getAttribute("name",ScriptContext.GLOBAL_SCOPE));

} catch(Exception e){

System.out.println("異常信息:"+e.getMessage());

}

}

執(zhí)行結(jié)果

3.1語言綁定對(duì)象

腳本執(zhí)行上下文中的最后一類信息是語言綁定對(duì)象。語言綁定對(duì)象也是與作用域相對(duì)應(yīng)的,同樣的作用域優(yōu)先級(jí)順序?qū)φZ言綁定對(duì)象也適用。這樣的優(yōu)先級(jí)順序會(huì)對(duì)腳本執(zhí)行時(shí)的變量解析產(chǎn)生影響。

語言綁定對(duì)象的優(yōu)先級(jí)順序的示例

/**

* 語言綁定對(duì)象的優(yōu)先級(jí)順序的示例

*/

public static void scriptContextBindings(){

try {

ScriptEngine engine = getJavaScriptEngine();

ScriptContext context = engine.getContext();

Bindings binding1 = engine.createBindings();

binding1.put("name","Arthur Ming");

context.setBindings(binding1,ScriptContext.GLOBAL_SCOPE);

Bindings binding2 = engine.createBindings();

binding2.put("name","明國賓");

context.setBindings(binding2,ScriptContext.ENGINE_SCOPE);

engine.eval("print(name)");

} catch (Exception e){

e.printStackTrace();

}

}

執(zhí)行結(jié)果

通過ScriptContext的setBindings方法設(shè)置的語言綁定對(duì)象會(huì)影響到ScriptEngine在執(zhí)行腳本時(shí)變量解析。ScriptEngine的put和get方法所操作的實(shí)際上就是ScriptContext中的作用域?yàn)镋NGINE_SCOPE的語言綁定對(duì)象。

通過腳本執(zhí)行上下文獲取語言綁定對(duì)象的示例

/**

* 通過腳本執(zhí)行上下文獲取語言綁定對(duì)象的示例

*/

public static void useScriptContextValues(){

try{

ScriptEngine engine = getJavaScriptEngine();

ScriptContext context = engine.getContext();

Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

bindings.put("name","Arthur Ming");

engine.eval("print(name)");

} catch (Exception e){

e.printStackTrace();

}

}

執(zhí)行結(jié)果

自定義屬性實(shí)際上也保存在語言綁定對(duì)象中。

自定義屬性保存在語言綁定對(duì)象中示例

/**

* 自定義屬性保存在語言綁定對(duì)象中示例

*/

public static void attributeInBindings(){

try{

ScriptEngine engine = getJavaScriptEngine();

ScriptContext context = engine.getContext();

context.setAttribute("name1","Arthur Ming",ScriptContext.GLOBAL_SCOPE);

context.setAttribute("name2","明國賓",ScriptContext.ENGINE_SCOPE);

engine.eval("print(name1);");

engine.eval("print(name2);");

}catch (Exception e){

e.printStackTrace();

}

}

執(zhí)行結(jié)果

總結(jié)

以上是生活随笔為你收集整理的java 脚本语言交互_Java学习笔记--脚本语言支持API的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。