Java 利用指令碼API執行Groovy指令碼的方式
阿新 • • 發佈:2018-12-27
Java執行指令碼語言的方式(以Groovy為例)
介紹
運用java Script API可以非常方便的執行能夠在JVM執行的指令碼程式,並通過其指令碼引擎進行引數傳遞等。
Java Scripting API 包含一組類和介面,在 javax.script 包中定義。這是一個相對比較小的 Java 包,以 ScriptEngineManager 類作為起點。一個 ScriptEngineManager 物件可以通過 JAR 檔案服務發現機制來查詢指令碼引擎(有點類似於JDBC, slf4J等),而例項化 ScriptEngine 物件的解析指令碼使用專門的指令碼語言編寫。更多關於 javax.script 包的詳細資訊請看 Java SE規範 http://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html
使用方法
maven引入Groovy引擎依賴
<!-- for executing groovy script -->
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version >2.4.12</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
<version>2.4.12</version>
<scope>runtime</scope>
</dependency>
</dependencies >
使用ScriptEngineManager獲取對應語言的指令碼引擎
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
通過engine物件執行指令碼語句,呼叫指令碼物件方法等
Bindings bindings = engine.createBindings();
bindings.put("name", "Johnson");
engine.eval("def getName(){return name;}", bindings);
示例封裝程式碼
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* 執行指令碼工具
*
* Created by xuyh at 2017年7月18日 上午11:05:49.
*/
public class ScriptUtils {
/**
* 指令碼語言groovy
*/
public static final String SCRIPT_GROOVY = "groovy";
/**
* 指令碼語言javascript
*/
public static final String SCRIPT_JAVASCRIPT = "javaScript";
private static ScriptEngineManager engineManager = new ScriptEngineManager();
/**
* 指令碼引擎快取
*/
private static Map<String, ScriptEngine> scriptEngineMap = new HashMap<>();
/**
* 獲取指令碼引擎
*
* @param scriptLang 指令碼語言 (groovy, javaScript, etc.)
* @return
*/
public static ScriptEngine getEngine(String scriptLang) {
ScriptEngine engine = scriptEngineMap.get(scriptLang);
if (engine == null) {
engine = engineManager.getEngineByName(scriptLang);
scriptEngineMap.put(scriptLang, engine);
}
return engine;
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param script 需要執行的指令碼文字
* @param bindings 給指令碼設定的全域性變數資料
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeScriptFunction(String scriptLang, String script, String functionName,
Map<String, Object> bindings)
throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
Bindings data = engine.createBindings();
for (String key : bindings.keySet()) {
data.put(key, bindings.get(key));
}
engine.eval(script, data);
return ((Invocable) engine).invokeFunction(functionName);
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param script 需要執行的指令碼文字
* @param args 執行指令碼方法傳入的引數
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeScriptFunction(String scriptLang, String script, String functionName, Object... args)
throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
engine.eval(script);
return ((Invocable) engine).invokeFunction(functionName, args);
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param bindings 給指令碼設定的全域性變數資料
* @param script 需要執行的指令碼文字
* @param args 執行指令碼方法傳入的引數
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeScriptFunction(String scriptLang, Map<String, Object> bindings, String script,
String functionName,
Object... args) throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
Bindings data = engine.createBindings();
for (String key : bindings.keySet()) {
data.put(key, bindings.get(key));
}
engine.eval(script, data);
return ((Invocable) engine).invokeFunction(functionName, args);
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param reader 需要執行的指令碼檔案
* @param bindings 給指令碼設定的全域性變數資料
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeFileScriptFunction(String scriptLang, Reader reader, String functionName,
Map<String, Object> bindings)
throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
Bindings data = engine.createBindings();
for (String key : bindings.keySet()) {
data.put(key, bindings.get(key));
}
engine.eval(reader, data);
return ((Invocable) engine).invokeFunction(functionName);
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param reader 需要執行的指令碼檔案
* @param args 執行指令碼方法傳入的引數
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeFileScriptFunction(String scriptLang, Reader reader, String functionName, Object... args)
throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
engine.eval(reader);
return ((Invocable) engine).invokeFunction(functionName, args);
}
/**
* 執行指令碼中的方法
*
* @param scriptLang 指令碼語言
* @param bindings 給指令碼設定的全域性變數資料
* @param reader 需要執行的指令碼檔案
* @param args 執行指令碼方法傳入的引數
* @param functionName 執行的方法名
* @return
* @throws ScriptException
* @throws NoSuchMethodException
*/
public static Object invokeFileScriptFunction(String scriptLang, Map<String, Object> bindings, Reader reader,
String functionName,
Object... args) throws ScriptException, NoSuchMethodException {
ScriptEngine engine = getEngine(scriptLang);
Bindings data = engine.createBindings();
for (String key : bindings.keySet()) {
data.put(key, bindings.get(key));
}
engine.eval(reader, data);
return ((Invocable) engine).invokeFunction(functionName, args);
}
}