当前位置: 首页 > news >正文

Java - JSR223规范解读_在JVM上实现多语言支持

文章目录

  • 1. 概述
  • 2. 核心目标
  • 3. 支持的脚本语言
  • 4. 主要接口
  • 5. 脚本引擎的使用
    • 执行JavaScript脚本
    • 执行groovy脚本
      • 1. Groovy简介
      • 2. Groovy脚本示例
      • 3. 如何在Java中集成 Groovy
      • 4. 集成注意事项
  • 6. 与Java集成
  • 7. 常见应用场景
  • 8. 优缺点
  • 9. 总结

在这里插入图片描述

1. 概述

JSR223(Java Specification Request 223),也称为 Scripting for the Java Platform,是一个Java平台的标准接口,旨在让Java应用程序能够灵活地集成和执行脚本语言。它定义了一种可以在Java应用中嵌入不同脚本语言的统一接口,允许Java程序调用、执行脚本,并且支持将Java对象传递到脚本语言中。


2. 核心目标

JSR223的目标是提供一种标准的API,以便Java应用能够:

  • 动态地执行脚本代码
  • 支持多个脚本语言
  • 将Java应用中的对象传递到脚本环境中

3. 支持的脚本语言

JSR223并没有指定哪些脚本语言必须支持,但它的设计理念是能够支持多种脚本语言。常见的支持脚本语言包括:

  • JavaScript (Nashorn / GraalVM)
  • Groovy
  • JRuby
  • Jython (Python)
  • Lua
  • BeanShell

不同的脚本语言通过JSR223接口进行集成,这些脚本引擎作为JSR223的实现进行交互。


4. 主要接口

JSR223定义了几个关键接口来实现Java与脚本语言的交互:

  • ScriptEngine: 这个接口代表了一个脚本引擎,允许Java代码与具体的脚本语言引擎进行交互。每个脚本引擎都实现了这个接口。
  • ScriptEngineFactory: 用于创建脚本引擎的工厂类。通过这个工厂类,Java程序可以获得可用的脚本引擎实例。
  • Bindings: 用于在Java和脚本之间传递变量和对象。Bindings允许在脚本执行期间使用Java对象。

常见的实现类:

  • Nashorn(从Java 8开始包含,用于执行JavaScript)
  • GraalVM(一个多语言执行环境,支持更多语言的集成)

5. 脚本引擎的使用

脚本引擎是JSR223的核心部分,接下来看几个例子

执行JavaScript脚本

样例一: 使用Nashorn引擎执行JavaScript代码的示例。

package com.artisan.jsr223;
import javax.script.*;public class JSR223Example {public static void main(String[] args) throws ScriptException {// 创建一个脚本引擎管理器ScriptEngineManager manager = new ScriptEngineManager();// 获取JavaScript引擎ScriptEngine engine = manager.getEngineByName("nashorn");// 执行JavaScript代码engine.eval("print('Hello, JSR223')");// 使用绑定传递变量Bindings bindings = engine.createBindings();bindings.put("name", "Artisan");engine.eval("print('Hello, ' + name);", bindings);}
}

在这个例子中,我们通过 ScriptEngineManager 获取Nashorn引擎,执行简单的JavaScript代码,使用 Bindings 传递变量。

在这里插入图片描述


样例二:

package com.artisan.jsr223;import javax.script.*;public class JSR223Example {public static void main(String[] args) throws Exception {// 获得JavaScript的脚本引擎ScriptEngineManager scriptEngineManager = new ScriptEngineManager();ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");// 进行脚本编译String script = "function process(){\n" +"var a=10;\n" +"var b=3;\n" +"return a*b-c;\n" +"}\n" +"process()";// 检查脚本引擎是否支持编译if (scriptEngine instanceof Compilable) {Compilable compilable = (Compilable) scriptEngine;CompiledScript compiledScript = compilable.compile(script);// 绑定Java的参数Bindings bindings = new SimpleBindings();bindings.put("c", 5);// 执行并打印结果Object result = compiledScript.eval(bindings);System.out.println(result);} else {System.out.println("当前脚本引擎不支持编译功能");}}
}

在这里插入图片描述


执行groovy脚本

1. Groovy简介

Groovy是一个基于Java平台的动态语言,它简洁、表达力强,并且与Java兼容性极高。Groovy可以作为Java的脚本引擎,直接在Java应用中使用。Groovy的语法简洁,支持面向对象、闭包、动态类型等特性,通常用于快速开发和扩展功能。

2. Groovy脚本示例

假设我们要编写一个简单的Groovy脚本,来计算一个人的年龄,并根据年龄判断是否符合某个年龄段(如成年)。

// 定义一个函数来计算年龄
def calculateAge(birthYear) {def currentYear = 2024return currentYear - birthYear
}// 定义一个函数来判断是否成年
def isAdult(age) {return age >= 18
}// 调用计算年龄和判断是否成年
def birthYear = 1990
def age = calculateAge(birthYear)println("Age: ${age}")
if (isAdult(age)) {println("You are an adult.")
} else {println("You are not an adult.")
}

解释:

  • def:用于定义变量或函数,Groovy是一种动态语言,变量和函数不需要显式声明类型。
  • calculateAge:该函数接受一个出生年份,返回计算后的年龄(2024年减去出生年份)。
  • isAdult:根据传入的年龄判断是否成年,成年为18岁及以上。
  • println:Groovy的内建方法,输出结果。

运行结果:

Age: 34
You are an adult.

3. 如何在Java中集成 Groovy

假设我们希望在Java代码中动态执行这个Groovy脚本,可以通过JSR223来实现。以下是如何在Java中嵌入并执行Groovy脚本的示例:


import javax.script.*;public class GroovyTest {public static void main(String[] args) throws ScriptException {// 创建一个脚本引擎管理器ScriptEngineManager manager = new ScriptEngineManager();// 获取Groovy引擎ScriptEngine engine = manager.getEngineByName("groovy");// 定义Groovy脚本String script ="def calculateAge(birthYear) { " +"    def currentYear = 2024; " +"    return currentYear - birthYear; " +"}\n" +  // 添加换行符"def isAdult(age) { " +"    return age >= 18; " +"}\n" +  // 添加换行符"def birthYear = 1990; " +"def age = calculateAge(birthYear); " +"println('Age: ' + age); " +"if (isAdult(age)) { " +"    println('You are an adult.'); " +"} else { " +"    println('You are not an adult.'); " +"} ";// 执行Groovy脚本engine.eval(script);}
}

步骤:

  1. 使用 ScriptEngineManager 获取Groovy引擎。
  2. 编写Groovy脚本并将其传递给引擎。
  3. 使用 eval() 方法执行脚本,并输出结果。

运行结果:

Age: 34
You are an adult.

4. 集成注意事项

  • Groovy的依赖:如果在Java项目中使用Groovy脚本,需要将Groovy的JAR包(例如 groovy-jsr223-x.y.z.jar)添加到项目的依赖中。

Maven依赖示例:

   <dependency><groupId>org.apache.groovy</groupId><artifactId>groovy-jsr223</artifactId><version>4.0.24</version></dependency>
  • 性能考虑:Groovy作为动态语言,性能可能不如纯Java代码,特别是在大规模或频繁执行的场景中,可能会引入一定的开销。

6. 与Java集成

  • 变量传递:JSR223允许将Java对象传递给脚本语言。通过 Bindings 接口,可以将Java对象存储在脚本的上下文中,脚本语言也能访问这些对象。

  • 动态执行:使用脚本语言可以动态地执行Java代码段,这对于快速开发和修改业务逻辑非常有效。例如,可以通过Java调用Groovy脚本来快速增加一些动态功能而无需重新编译整个应用。


7. 常见应用场景

JSR223可以广泛应用于多个领域:

  • 动态配置和脚本扩展:在Java应用中使用脚本来动态修改行为。例如,可以用Groovy编写自定义的配置文件解析器。
  • 自动化测试:集成脚本语言用于编写自动化测试脚本。
  • Web应用:在Web应用中,使用JSR223集成脚本语言来编写自定义插件或扩展功能。例如,支持JavaScript来扩展服务器端的业务逻辑。
  • 数据处理:在Java应用中使用脚本来处理数据或执行算法。

8. 优缺点

优点:

  • 灵活性:脚本语言的引入使得Java应用能够动态修改行为,增加了灵活性。
  • 简化开发:无需重新编译整个Java应用,可以动态执行脚本。
  • 多语言支持:能够使用多种脚本语言,适应不同开发者的需求。

缺点:

  • 性能问题:执行脚本语言可能比直接执行Java代码慢,尤其是当脚本频繁执行时。
  • 维护性问题:使用脚本时,可能会增加代码的复杂性,特别是当脚本代码没有很好地组织和文档化时。
  • 调试困难:脚本代码的调试相对困难,尤其是当脚本与Java代码紧密集成时。

9. 总结

JSR223提供了一个标准的接口来将脚本语言集成到Java应用中,支持多个脚本引擎和多种脚本语言的调用。它可以极大地提升Java应用的灵活性和扩展性,尤其适用于动态修改应用行为的场景。然而,使用JSR223时也要注意性能和维护性问题。

在这里插入图片描述

相关文章:

Java - JSR223规范解读_在JVM上实现多语言支持

文章目录 1. 概述2. 核心目标3. 支持的脚本语言4. 主要接口5. 脚本引擎的使用执行JavaScript脚本执行groovy脚本1. Groovy简介2. Groovy脚本示例3. 如何在Java中集成 Groovy4. 集成注意事项 6. 与Java集成7. 常见应用场景8. 优缺点9. 总结 1. 概述 JSR223&#xff08;Java Spe…...

win10系统部署RAGFLOW+Ollama教程

本篇主要基于linux服务器部署ragflowollama&#xff0c;其他操作系统稍有差异但是大体一样。 一、先决条件 CPU ≥ 4核&#xff1b; RAM ≥ 16 GB&#xff1b; 磁盘 ≥ 50 GB&#xff1b; Docker ≥ 24.0.0 & Docker Compose ≥ v2.26.1。 如果尚未在本地计算机&#xff…...

基于Python制作一个简易UI界面

基于Python制作一个简易UI界面 目录 基于Python制作一个简易UI界面1 原理简介2 编写程序3 程序测试 1 原理简介 这里用到了Python自带的UI库tkinter。 tkinter 是 Python 的标准 GUI&#xff08;图形用户界面&#xff09;库&#xff0c;用于创建和管理图形界面。它提供了一个简…...

鲁菜大师程伟华到访金宫川派味业

共工新闻社11月29日电&#xff08;范琦&#xff09;上周&#xff0c;中国鲁菜大师、首批中国烹饪大师名厨程伟华到访金宫川派味业总部基地。这位从厨51年、坚持传承鲁菜的行业大师人物&#xff0c;深入了解了金宫川派的品牌文化&#xff0c;参观了金宫自动生产车间&#xff0c;…...

Linux设置jar包开机自启动

本文详细描述了如何在Linux服务器上创建并配置jar包的自启动脚本&#xff0c;包括编辑/etc/init.d/jar_auto.sh以设置环境变量&#xff0c;将jar包添加到rc.local以开机启动&#xff0c;以及提升脚本文件权限确保自动执行。 1、准备工作 Linux中Java的路径 项目jar包绝对路径 2…...

IoTDB 常见问题 QA 第一期

开始&#xff01;关于 IoTDB 的 Q&A 我们将定期汇总社区讨论频繁的问题&#xff0c;并展开进行详细回答&#xff0c;通过积累常见问题“小百科”&#xff0c;方便大家使用 IoTDB。 Q1&#xff1a;WAL 堆积导致写入失败 问题及现象 集群报错&#xff1a; The write is rejec…...

【linux学习指南】linux捕捉信号

文章目录 &#x1f4dd;前言&#x1f320; 信号捕捉的流程&#x1f309; sigaction &#x1f320;穿插话题-操作系统是怎么运⾏的&#x1f309; 硬件中断&#x1f309;时钟中断 &#x1f6a9;总结 &#x1f4dd;前言 &#x1f320; 信号捕捉的流程 如果信号的处理动作是⽤⼾⾃定…...

git如何快速拉取已经提交的mr进行验证

参考&#xff1a;https://stackoverflow.com/questions/44992512/how-to-checkout-merge-request-locally-and-create-new-local-branch Pull merge request to new branch git fetch origin merge-requests/REQUESTID/head:BRANCHNAME i.e git fetch origin merge-requests/…...

【阿来来gis规划师工具箱说明书】h07四分标注

背景 在做arcmap的四分标注前&#xff0c;已经做好了二行三行的标注&#xff0c;以及在pro中做好了四分标注。这个四分标注做了好些版本&#xff0c;都达不到想要的效果。最终使用了静态标注的形式来做。 制作思路 新建两个承接标注文字的文本字段&#xff0c;考虑一般标注超…...

【大数据学习 | 面经】HDFS的三副本机制和编码机制

1. hdfs的三副本机制 hdfs的三副本机制是其核心特性之一&#xff0c;旨在确保数据的高可用性和容错性。通过将每个文件的数据块复制三个副本&#xff0c;并分散存储在不同的DateNode上&#xff0c;hdfs能够在节点故障的时候提供数据冗余和持续访问的能力。 三副本机制的工作原…...

lua-cjson 例子

apt install -y lua-cjson 安装 编辑 tmp.lua cjson require "cjson" p 666 d "23.42" payload{"d":[{"pres":..(p)..,"temp":"..(d).."}]} print("payload " .. payload) j cjson.decode(payloa…...

java面向对象知识点: 封装,构造,重载

目录 封装 封装知识点 private&#xff08;私有&#xff09; public&#xff08;公共&#xff09; 二、getter和setter方法 getter方法&#xff08;访问器方法&#xff09; setter方法&#xff08;修改器方法&#xff09; 三、封装类的设计原则 单一职责原则 高内聚性 一…...

go的math/rand随机数生成器

伪随机数生成器&#xff0c;默认情况下随机数种子是固定的&#xff0c; **注意&#xff1a;**固定的随机数种子每次生成的随机数都是相同的随机数序列 一、基础用法 math/rand 包提供了随机数生成的方法。常用的函数包括&#xff1a; rand.Int()&#xff1a;返回一个伪随机…...

JiaJia-CP-1,2,3的WP(2)

一.JiaJia-CP-2 一看题目&#xff0c;聊天软件&#xff0c;用的什么聊天软件直接userassist看运行过什么程序 vol -f JiaJia_Co.raw --profileWin7SP1x64 userassist 发现Telegram.exe(小飞机) 可能性很大啊(真是个摸鱼大神) 除此之外&#xff0c;filescan也能看到&#xff0…...

3DMAX星空图像生成器插件使用方法详解

3DMAX星空图像生成器插件&#xff0c;一键生成星空或夜空的二维图像。它可用于创建天空盒子或空间场景&#xff0c;或作为2D艺术的天空背景。 【主要特点】 -单击即可创建星空图像或夜空。 -星数、亮度、大小、形状等参数。 -支持任何图像大小&#xff08;方形&#xff09;。…...

ROS2 系列学习教程(总目录)

ROS2Learning ROS1 系列学习教程(总目录) 一、ROS2 简介 1.1 ROS2简介及学习资源汇总 二、ROS2 基础 2.1 ROS2安装详细教程&#xff08;以Humble为例&#xff09; 2.2 ROS2 构建系统 colcon 介绍、安装与使用 2.3 ROS2 与 ROS1 编码方式对比 ROS2 与 ROS1 编码方式对比&am…...

[GKCTF 2021]签到

[GKCTF 2021]签到 wireshark跟踪http流&#xff0c;基本编解码&#xff0c;倒叙&#xff0c;栅栏密码 找到cat /f14g 把包里返回的字符串先hex解码&#xff0c;再base64解码&#xff0c;看到一个时间是倒叙&#xff0c;不含flag 继续往下面翻&#xff0c;可以看到cat%2Ff14g%7…...

Kubernetes——part11 云原生中间件上云部署 Rocketmqkafkazookeeper

Rocketmq rocketmq角色 RocketMQ由四部分构成&#xff1a;Producer、Consumer、Broker和NameServer 启动顺序&#xff1a;NameServer->Broker 为了消除单点故障&#xff0c;增加可靠性或增大吞吐量&#xff0c;可以在多台机器上部署多个nameserver和broker&#xff0c;并…...

ip租期到了

当IP租约到期后&#xff0c;会发生以下过程&#xff1a; 租约到期通知&#xff1a;在租约到期之前&#xff0c;DHCP客户端通常会尝试续租其IP地址。如果客户端仍然活跃并且希望继续使用相同的IP地址&#xff0c;它会向DHCP服务器发送一个DHCP请求&#xff08;DHCPREQUEST&#…...

鸿蒙系统(harmony)支持Android应用的双框架技术架构分析

鸿蒙系统(HarmonyOS)支持 Android 应用的双框架技术架构 是为了在鸿蒙操作系统上实现对 Android 应用的兼容与支持,特别是在多设备生态下,确保不同类型的 Android 应用能够无缝运行在鸿蒙设备上。这种双框架架构使鸿蒙能够兼顾自身的原生应用生态和 Android 的广泛应用生态…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...