Java 的脚本引擎(Script Engine)是 Java 语言的一部分,允许开发者在 Java 应用程序中嵌入和执行脚本语言。它提供了一种灵活的方式来动态执行代码,进行计算和逻辑处理。以下是对 Java 脚本引擎的详细介绍:
背景与用途
Java 脚本引擎是 Java 6 引入的,属于 javax.script
包的一部分。它使得 Java 应用程序能够执行多种脚本语言(如 JavaScript、Groovy、Ruby 等),这对于需要动态行为或灵活配置的应用程序非常有用。
核心接口
Java 脚本引擎主要通过以下几个核心接口进行操作:
ScriptEngineManager
:- 用于创建脚本引擎的工厂类。可以通过它获取支持特定脚本语言的引擎实例。
ScriptEngine
:- 代表一个脚本引擎的实例。提供了执行脚本和管理脚本上下文的方法。
- 主要方法:
eval(String script)
:执行给定的脚本并返回结果。put(String key, Object value)
:将变量添加到引擎的上下文中。get(String key)
:从上下文中获取变量的值。
Bindings
:- 用于存储脚本引擎的变量和参数。可以在脚本中访问和修改这些变量。
支持的脚本语言
Java 脚本引擎支持多种脚本语言,最常用的包括:
- JavaScript:通过 Nashorn 引擎(在 Java 8 中引入,Java 15 后被移除)。
- Groovy:一种动态语言,常用于构建脚本和 DSL(领域特定语言)。
- Ruby:通过 JRuby 支持。
- Python:通过 Jython 支持。
优势
- 动态性:可以在运行时动态执行代码,适合需要灵活配置的应用。
- 多语言支持:支持多种脚本语言,开发者可以选择最适合其需求的语言。
- 集成性:可以与 Java 代码无缝集成,利用 Java 的强大功能和库。
注意事项
- 脚本引擎的性能可能不如纯 Java 代码,尤其是在频繁调用时。
- 安全性:执行不受信任的脚本可能导致安全问题,因此需要谨慎处理。
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.HashMap;
import java.util.Map;
/**
* @author : zanglikun
* @date : 2025/1/14 下午1:49
* @desc : 表达式工具
*/
public class ScriptEngineUtil {
private static ScriptEngine engine;
static {
engine = new ScriptEngineManager().getEngineByName("JavaScript");
addCustomMethods(engine);
}
private static void addCustomMethods(ScriptEngine engine) {
// 添加自定义方法到引擎
engine.put("includes", (IncludesFunction) (String str, String substring) -> str.contains(substring));
}
// 自定义方法接口
@FunctionalInterface
public interface IncludesFunction {
boolean includes(String str, String substring);
}
private static boolean evaluateExpression(ScriptEngine engine, String expression, Map<String, Object> params) throws ScriptException {
// 将参数注入到表达式中
for (Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// 将参数替换为其值
expression = expression.replace(key, value instanceof String ? "\"" + value + "\"" : value.toString());
}
// 执行表达式并返回结果
return (Boolean) engine.eval(expression);
}
@SneakyThrows
public static boolean evaluateExpression(String expression, Map<String, Object> params) throws ScriptException {
if (StringUtils.isBlank(expression)){
return true;
}
// 将参数注入到表达式中
for (Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// 将参数替换为其值
expression = expression.replace(key, value instanceof String ? "\"" + value + "\"" : value.toString());
}
// 执行表达式并返回结果
return (Boolean) engine.eval(expression);
}
public static void main(String[] args) {
// 创建一个脚本引擎
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
// 添加自定义方法
addCustomMethods(engine);
// 示例参数
Map<String, Object> params = new HashMap<>();
params.put("key1", 1); // 可以是 1 或 0
params.put("key2", 1); // 可以是 1 或 0
params.put("key3", "YWJG,OTHER_TYPE"); // 示例字符串
// 示例表达式
String expression1 = "(key1 != 1 && key2 == 1)";
String expression4 = "(key1 != 1 && includes(key3, 'YWJG'))";
String expression5 = "(includes(key3,'YWJG'))";
// 验证表达式
try {
System.out.println("Expression 1: " + evaluateExpression(engine, expression1, params)); // false
System.out.println("Expression 4: " + evaluateExpression(engine, expression4, params)); // false
System.out.println("Expression 5: " + evaluateExpression(engine, expression5, params)); // true
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
注意事项
JDK15移除库,不支持功能了,如果有高 JDK 的场景,各位自行询问 GPT 引入外部库,或新类型的脚本。
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤