Java通过Nashorn引擎动态执行JavaScript脚本
本文介绍如何在Java中利用内置的JavaScript引擎(如Nashorn)动态执行JS脚本,以实现系统功能的灵活扩展。通过Gson将复杂Java对象转换为JSON格式供JS使用,并结合动态代理机制,实现无需具体实现类的接口方法。文章提供了从参数绑定、脚本执行到返回值处理的完整工具类示例及测试代码,展示了Java与JS交互的核心原理。
Java执行JavaScript脚本的工具实现
Java执行JavaScript脚本的工具实现
目的:为了增强系统的可扩展性,引入JavaScript脚本支持,允许通过执行脚本来实现更复杂的功能逻辑。
应用场景:系统提供的接口可以不依赖具体的Java实现类,而是通过动态加载并执行JavaScript脚本来实现接口方法。这种机制只要灵活运用,适用场景非常广泛。
基础工具类与原理
首先介绍一个基础的工具类

实际上,掌握这一个工具类已足够应对后续示例,后续内容均基于此工具类展开。
代码原理说明:
Java内置的JavaScript引擎默认无法直接访问List、Map等复杂Java对象的属性。因此,该工具类遍历params中的所有key,利用Gson将value转换为JSON字符串,再通过eval执行类似var key = {...};的语句。执行后,引擎中便生成了可遍历的key变量,从而使得复杂对象能在JS引擎中被正常使用。
注意事项:
可以通过:
Binds bs = engine.getBindings(ScriptContext.ENGINE_SCOPE);获取脚本引擎作用域内的所有变量。此外,还可以将Java对象绑定到engine中,进而调用对象的方法。例如调用Dao或Service层的方法,甚至尝试调用数据库相关方法都是可行的。
若需使用对象的属性,必须按照上述方式进行转换处理。
利用JavaScript实现Java接口
以下是一个使用该工具类的简单示例。
利用JavaScript实现Java接口
这仅是一个基础示例,其中动态代理的原理已在《MyBatis接口的简单实现原理》一文中介绍。本例未实现MyBatis那样强大的功能,仅为演示目的,Java端仅包含单接口方法。
代理类实现
代理类实现

该类需接收脚本内容,接口方法参数需带有@JsParam注解。convertArgs方法负责将参数转换为适合JSUtil工具类使用的Map类型,随后传入script脚本及参数执行。执行完毕后,通过ConvertUtils工具转换返回值类型,最终返回结果。
@JsParam注解定义
@JsParam注解定义

由于低版本Java无法直接获取参数名,此处通过简单的注解来获取名称。
注解中设置的名称即为脚本中可直接使用的参数名。
代理工厂类
代理工厂类

一个简单的工厂类实现。
测试代码示例
测试代码示例
测试使用的接口定义

注: 接口定义简单,但参数类型可以是List<User>等复杂对象。 你可以在JS脚本中按照JSON格式使用所有值。
测试代码实现

注意脚本中的num1和num2,必须与接口中定义的注解名保持一致。
更特殊的脚本写法如下:
var sum = num1+num2;
sum;
这里需要注意返回值的方式,即将要返回的值写在最下方。不能写成return sum;。不清楚这是否与函数式编程有关,如有了解者,欢迎留言回复。
输出结果
100
总结
虽然此例直接使用的意义有限,但其中包含的原理对设计JS脚本功能有一定帮助。在Java中,通过JS作为扩展手段是容易实现的。
总结
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。如果你想了解更多相关内容请查看下面相关链接
JS脚本在App中运行报错怎么解决
2026-11-04 23:11:03
JS怎么使用padStart方法给数字补零
2026-11-04 11:12:03
JS是什么意思?JavaScript全称及基本定义
2026-11-04 08:05:29
JS 使用 toFixed(1) 保留一位小数的基本用法与注意事项
2026-11-03 18:34:57
JS字符串转整数:parseInt与Number的区别及用法
2026-11-03 17:26:54
