华南俳烁实业有限公司

考試首頁 | 考試用書 | 培訓(xùn)課程 | 模擬考場 | 考試論壇  
  當前位置:設(shè)計制作 > JavaScript > 文章內(nèi)容
  

使用腳本實現(xiàn)設(shè)計和性能的平衡

 [ 2017年8月19日 ] 【

眾所周知,各種語言都有各自的特點,有的語言可以通過動態(tài)類型或動態(tài)閉包之類的特性為我們帶來好處。許多資料都介紹了如何通過特定語言中的具體特性來簡化編程,或者使用應(yīng)用程序具有炫酷的功能,如此等等。但是,用戶可能只會使用腳本實現(xiàn) Java 應(yīng)用程序中的一部分,因此這里有一個經(jīng)常被人忽略的問題:應(yīng)該在何時以何種方式使用腳本語言?

在本文中,我將介紹 Scripting API 中的一些高級概念,并演示它們?nèi)绾螏椭?Java 應(yīng)用程序中成功地使用腳本。

在 JVM 中使用腳本語言的基本條件是擁有一個可通過 Java 訪問的解釋程序(也稱作引擎)。有兩種常用的方法可實現(xiàn)此目的:在 Java 中實現(xiàn)引擎或在本機語言解釋程序外設(shè)計一個 Java 封裝器。腳本引擎的特性各不相同(詳見下文),但是其中很少能代表每個解釋程序的核心功能。每個引擎都應(yīng)該能夠為腳本的執(zhí)行(evaluation)提供上下文,并且顯然應(yīng)該能夠執(zhí)行腳本。

在最簡單的場景中,我們將在 Java 應(yīng)用程序中針對一些語言實例化一個腳本引擎,并綁定一些變量為引擎提供上下文,然后在某個時刻執(zhí)行腳本。此后,我們還可以從引擎上下文獲取一些變量值,因為被執(zhí)行的代碼可以修改(或設(shè)置)這些值。

顯然,框架需要抽象出各種腳本引擎并借此為 Java 應(yīng)用程序創(chuàng)建通用的腳本支持。Java SE 6 中的 Scripting API( javax.script)就是出于這種目的。它支持簡單的引擎注冊、通過工廠方法實例化引擎,以及在方法之間共享上下文。

在本文中,我將主要介紹其他一些方面。如今,許多可用的腳本引擎都向開發(fā)人員提供了較多的特性用于簡化腳本執(zhí)行。其中一個特性便是能夠調(diào)用腳本中定義的獨立的函數(shù)和對象方法。在一些語言中,您甚至還可以在腳本中實現(xiàn)整個 Java 接口并在 Java 中把它們當作常規(guī)對象使用。我們將看到,這些特性可以極大地影響我們在應(yīng)用程序中使用腳本的方式。但是首先,我必須了解 Scripting API 如何支持這些特性。

javax.script.Invocable

Scripting API 的主要設(shè)計目的之一就是盡可能的實現(xiàn)通用性。這樣眾多腳本引擎便可以依照它。鑒于此,javax.script.ScriptEngine 接口只定義了最基本的腳本引擎操作:變量綁定和腳本執(zhí)行。腳本引擎可以實現(xiàn)的所有其他高級特性都封裝在一個單獨的接口中,這樣開發(fā)人員便可以輕易地判斷特定引擎的特征并適當?shù)厥褂盟。這種體系結(jié)構(gòu)還允許通過此 API 使用非常簡單的引擎。

函數(shù)

在以下示例中,我將演示 Invocable 接口。首先,我將創(chuàng)建一個簡單的腳本(本文的所有示例都將通過 JavaScript 實現(xiàn),因此可以使用 JKD 6 中的 Rhino 引擎 來執(zhí)行它們):

function sayHello(name) {
     println("Hello " + name);
}

這個簡單的 JavaScript 示例位于 function.js 文件中(并且可從本文的 參考資料 部分獲得),其中定義了一個 sayHello 函數(shù),用于向標準輸出打印文本。現(xiàn)在,我們來看看如何使用 Scripting API 調(diào)用這種函數(shù)。

package net.scriptinginjava.invocable;
import java.io.FileReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class InvocableTest {
   public static void main(String[] args) throws Exception {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("js");
    if (engine instanceof Invocable) {
     engine
      .eval(new FileReader(
       "src/net/scriptinginjava/invocable/function.js"));
     ((Invocable) engine).invokeFunction("sayHello", "World");
    }
   }
}

這個 Java 應(yīng)用程序?qū)嵗?ScriptEngineManager 類,并使用該實例獲取需要的腳本引擎,然后使用該引擎處理腳本。

Invocable 接口的使用非常有趣。如您所見,如果引擎實現(xiàn)了 Invocable 接口,則 Java 開發(fā)人員可以使用它的 InvokeFunction 方法調(diào)用之前被處理腳本中的函數(shù)。該方法使用函數(shù)名稱作為第一個參數(shù),另一個參數(shù)是 Object 變量(varargs)的變量名稱。在本例中,代碼將調(diào)用 sayHello 函數(shù)和將 World 變量傳遞給該函數(shù)。結(jié)果,代碼將通過標準輸出打印出“Hello World”文本。

本文糾錯】【告訴好友】【打印此文】【返回頂部
將考試網(wǎng)添加到收藏夾 | 每次上網(wǎng)自動訪問考試網(wǎng) | 復(fù)制本頁地址,傳給QQ/MSN上的好友 | 申請鏈接 | 意見留言 TOP
關(guān)于本站  網(wǎng)站聲明  廣告服務(wù)  聯(lián)系方式  站內(nèi)導(dǎo)航  考試論壇
Copyright © 2007-2013 中華考試網(wǎng)(Examw.com) All Rights Reserved
文化| 正安县| 威远县| 柞水县| 军事| 罗山县| 南京市| 南通市| 交城县| 江口县| 嵊泗县| 夏河县| 多伦县| 淮安市| 兰州市| 阳原县| 胶南市| 山阳县| 包头市| 汤原县| 百色市| 兴仁县| 静乐县| 桐庐县| 虹口区| 普陀区| 南涧| 葵青区| 寿阳县| 桓仁| 广宁县| 务川| 安丘市| 庄河市| 都匀市| 大庆市| 平塘县| 斗六市| 新沂市| 乳山市| 内江市|