1. 程式人生 > >Java 利用指令碼API執行Groovy指令碼的方式

Java 利用指令碼API執行Groovy指令碼的方式

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);
    }
}