热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java脚本引擎性能_Java脚本引擎入门

JavaScriptEngineJava脚本引擎可以将脚本嵌入Java代码中,可以自定义和扩展Java应用程序,自JDK1.6被引入,基于

6d14101f89fa97666102b4998cef4dfc.png

Java Script Engine

Java 脚本引擎可以将脚本嵌入Java代码中,可以自定义和扩展Java应用程序,自JDK1.6被引入,基于Rhino引擎,JDK1.8后使用Nashorn引擎,支持ECMAScript 5,但后期还可能会换。

脚本引擎包位于javax.script中,各个类名及描述如下

接口

Bindings

键值对映射,所有key都为String

Compilable

由具体的脚本引擎实现,用于将脚本进行编译,可重复使用。

Invocable 由具体的脚本引擎实现,其允许调用先前已执行的脚本

ScriptContext

脚本引擎上下文,用于将应用程序与脚本引擎进行绑定

ScriptEngine

由具体的脚本引擎实现,定义了执行脚本的方法、键值对映射关系、脚本引擎上下文

ScriptEngineFactory

脚本引擎工厂,每一个ScriptEngine都有一个对应的工厂。ScriptEngineManager会从ClassLoader中获取所有的ScriptEngineFactories实例

AbstractScriptEngine

ScriptEngine的抽象实现类,提供了ScriptEngine的标准实现

CompiledScript

由存储编译结果的类扩展。可以以Java类、Java类文件或者脚本操作码的形式存储,可以重复执行无需重新解析。每个CompiledScript都与一个ScriptEngine相关联,调用CompiledScript的eval方法会导致ScriptEngine执行

ScriptEngineManager

脚本引擎管理器,提供ScriptEngine的实例化机制,并维护了一些键/值对集合,供所有创建的ScriptEngine共享使用

SimpleBindings

使用HashMap 或者其他Map实现的一种简单键值映射

SimpleScriptContext

ScriptContext 的一种简单实现

异常

ScriptException

脚本API的通用异常类,抛出的异常类具有文件名、行号、列号信息

示例

简单的

@Test

public void scriptTest() throws ScriptException{

ScriptEngineManager engineManager = new ScriptEngineManager();

//获取Javascript解析引擎

ScriptEngine engine = engineManager.getEngineByName("Javascript");

//将x变量映射为Hello World!

engine.put("x", "Hello World!");

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

}

//输出

//Hello World!

较复杂的

从文件中读取脚本

/**

* 从文件中读取Js脚本

* test.js 中的内容:

* var obj = new Object();

* obj.hello = function (name) {

* print('Hello, ' + name);

* }

* @throws Exception

*/

@Test

public void file() throws Exception{

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("Javascript");

engine.eval(new FileReader(new File("script/test.js")));

Invocable inv = (Invocable) engine;

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

inv.invokeMethod(obj, "hello", "Script Test!" );

}

将Java变量注入脚本中

有可能需要在脚本中使用Java变量

@Test

public void scriptVar() throws Exception{

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("Javascript");

File file = new File("F:/test/test.txt");

//将File对象f直接注入到js脚本中并可以作为全局变量使用

engine.put("files", file);

engine.eval("print(files.getPath());print(files.getName());");

}

调用脚本中的方法

使用Invocable 调用已经加载脚本中的方法

@Test

public void scriptTest1() throws ScriptException, NoSuchMethodException{

ScriptEngineManager engineManager = new ScriptEngineManager();

ScriptEngine engine = engineManager.getEngineByName("Javascript");

StringBuilder sb = new StringBuilder();

sb.append("var obj = new Object();");

sb.append("obj.hello = function(name){print('Hello, ' + name);}");

engine.eval(sb.toString());

//Invocable 可以调用已经加载过的脚本

Invocable invocable = (Invocable) engine;

//获取脚本的obj对象

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

//调用obj对象的hello函数

invocable.invokeMethod(object, "hello", "Script Method!");

}

//输出

//Hello, Script Method!

多个作用域

一个脚本引擎,多个scope,x变量并没有覆盖之前的变量

@Test

public void scriptTest() throws ScriptException{

ScriptEngineManager engineManager = new ScriptEngineManager();

ScriptEngine engine = engineManager.getEngineByName("Javascript");

engine.put("x", "Hello World!");

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

ScriptContext context = new SimpleScriptContext();

//新的Script context绑定ScriptContext的ENGINE_SCOPE

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

// 增加一个新变量到新的范围 engineScope 中

bindings.put("x", "word hello!!");

// 执行同一个脚本 - 但这次传入一个不同的script context

engine.eval("print(x);", bindings);

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

}

//输出

//Hello World!

//word hello!!

//Hello World!

使用脚本实现Java接口

@Test

public void runnableImpl() throws Exception{

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("Javascript");

// String里定义一段Javascript代码脚本

String script = "function run() { print('run called'); }";

// 执行这个脚本

engine.eval(script);

// 从脚本引擎中获取Runnable接口对象(实例). 该接口方法由具有相匹配名称的脚本函数实现。

Invocable inv = (Invocable) engine;

// 在上面的脚本中,我们已经实现了Runnable接口的run()方法

Runnable runnable = inv.getInterface(Runnable.class);

// 启动一个线程运行上面的实现了runnable接口的script脚本

Thread thread = new Thread(runnable);

thread.start();

Thread.sleep(1000);

}

如果脚本是基于对象的,则可以通过执行脚本的方法来实现Java接口,避免调用脚本的全局函数。

@Test

public void runnableObject() throws ScriptException{

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("Javascript");

String script = "var obj = new Object();obj.run = function() {println('run method called')}";

engine.eval(script);

//获得脚本对象

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

Invocable invocable = (Invocable) engine;

Runnable runnable = invocable.getInterface(object, Runnable.class);

Thread thread = new Thread(runnable);

thread.start();

Thread.sleep(1000);

}



推荐阅读
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文比较了eBPF和WebAssembly作为云原生VM的特点和应用领域。eBPF作为运行在Linux内核中的轻量级代码执行沙箱,适用于网络或安全相关的任务;而WebAssembly作为图灵完备的语言,在商业应用中具有优势。同时,介绍了WebAssembly在Linux内核中运行的尝试以及基于LLVM的云原生WebAssembly编译器WasmEdge Runtime的案例,展示了WebAssembly作为原生应用程序的潜力。 ... [详细]
author-avatar
啊明的小蝴蝶_522
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有