Java 调用函数的推荐方法(是否使用CompiledScript?)
我正在编写一个库,它提供了在JVM上以各种非Java语言执行的宏支持。想想JavaScript、Ruby等 因此,我想使用JSR-223脚本API 这个API有一个Java 调用函数的推荐方法(是否使用CompiledScript?),java,groovy,scripting,jruby,jsr223,Java,Groovy,Scripting,Jruby,Jsr223,我正在编写一个库,它提供了在JVM上以各种非Java语言执行的宏支持。想想JavaScript、Ruby等 因此,我想使用JSR-223脚本API 这个API有一个CompiledScript类的概念,我认为这是在加载时预编译脚本并在执行时重用脚本的最佳方法 检查ScriptEngine是否是可编译的实例,如果是,则使用CompiledScript方法,否则只需评估ScriptEngine本身中的函数,这是一种好的做法吗 例如(简化): 在这种情况下,使用CompiledScript是否有好处,
CompiledScript
类的概念,我认为这是在加载时预编译脚本并在执行时重用脚本的最佳方法
检查ScriptEngine
是否是可编译的
实例,如果是,则使用CompiledScript
方法,否则只需评估ScriptEngine
本身中的函数,这是一种好的做法吗
例如(简化):
在这种情况下,使用CompiledScript
是否有好处,还是可以忽略
我的实际实现稍微高级一点,并且是一个单独的加载和调用模式,用于重用实际的编译脚本
:
public void load(String name, String[] code) {
if (scriptEngine == null) {
logger.warn("Cannot load macro '{}' as no script engine was found for '{}'", name, scriptEngineShortName);
} else {
// Create a unique function name called the same as the object macro name.
String function = resolveFunctionCode(name, code);
try {
if (scriptEngine instanceof Compilable) {
// Compile the code.
CompiledScript compiledFunction = ((Compilable) scriptEngine).compile(function);
compiledFunction.eval();
compiledFunctions.put(name, compiledFunction);
} else {
// Run the code to load the function into the script engine.
scriptEngine.eval(function);
}
} catch (ScriptException e) {
logger.error("Error loading code for marco '{}'", name, e);
}
}
}
public String call(String name, String[] fields) {
String result = null;
if (scriptEngine == null) {
logger.warn("Cannot call macro '{}' as no script engine was found for '{}'", name, scriptEngineShortName);
} else {
try {
Invocable invocable = null;
if (scriptEngine instanceof Compilable) {
if (compiledFunctions.containsKey(name)) {
CompiledScript compiledFunction = compiledFunctions.get(name);
invocable = (Invocable) compiledFunction.getEngine();
}
} else {
invocable = (Invocable) scriptEngine;
}
if (invocable != null) {
Object value = invocable.invokeFunction(resolveFunctionName(name), rs, fields);
if (value != null) {
result = value.toString();
}
} else {
logger.warn("Cannot call macro '{}' as no function was found", name);
}
} catch (ScriptException e) {
logger.error("Error invoking function for macro '{}'", name, e);
} catch (NoSuchMethodException e) {
logger.error("Error invoking function for macro '{}'", name, e);
}
}
return result;
}
public void load(String name, String[] code) {
if (scriptEngine == null) {
logger.warn("Cannot load macro '{}' as no script engine was found for '{}'", name, scriptEngineShortName);
} else {
// Create a unique function name called the same as the object macro name.
String function = resolveFunctionCode(name, code);
try {
if (scriptEngine instanceof Compilable) {
// Compile the code.
CompiledScript compiledFunction = ((Compilable) scriptEngine).compile(function);
compiledFunction.eval();
compiledFunctions.put(name, compiledFunction);
} else {
// Run the code to load the function into the script engine.
scriptEngine.eval(function);
}
} catch (ScriptException e) {
logger.error("Error loading code for marco '{}'", name, e);
}
}
}
public String call(String name, String[] fields) {
String result = null;
if (scriptEngine == null) {
logger.warn("Cannot call macro '{}' as no script engine was found for '{}'", name, scriptEngineShortName);
} else {
try {
Invocable invocable = null;
if (scriptEngine instanceof Compilable) {
if (compiledFunctions.containsKey(name)) {
CompiledScript compiledFunction = compiledFunctions.get(name);
invocable = (Invocable) compiledFunction.getEngine();
}
} else {
invocable = (Invocable) scriptEngine;
}
if (invocable != null) {
Object value = invocable.invokeFunction(resolveFunctionName(name), rs, fields);
if (value != null) {
result = value.toString();
}
} else {
logger.warn("Cannot call macro '{}' as no function was found", name);
}
} catch (ScriptException e) {
logger.error("Error invoking function for macro '{}'", name, e);
} catch (NoSuchMethodException e) {
logger.error("Error invoking function for macro '{}'", name, e);
}
}
return result;
}