1. 程式人生 > >Java動態調用腳本語言Groovy

Java動態調用腳本語言Groovy

nts tac 輸出 integer empty lena exce cat bsp

Java動態調用腳本語言Groovy

2019-05-15

目錄

0. pom.xml添加依賴
1. 使用GroovyShell計算表達式
2. 使用GroovyScriptEngine腳本引擎加載Groovy腳本
3. 使用GroovyClassLoader動態地載入Groovy的類
4. 使用JAVA腳本API

0. pom.xml添加依賴

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>
groovy-all</artifactId> <version>2.5.6</version> <type>pom</type> </dependency>

1.使用GroovyShell計算表達式

使用Binding對象將變量傳入表達式,並通過GroovyShell返回表達式的計算結果。

GroovyShellExample.java

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

public class GroovyShellExample { public static void main(String args[]) { Binding binding = new Binding(); binding.setVariable("x", 10); binding.setVariable("language", "Groovy"); GroovyShell shell = new GroovyShell(binding); Object value = shell.evaluate("println \"Welcome to $language\"; y = x * 2; z = x * 3; return x "); System.err.println(value
+", " + value.equals(10)); System.err.println(binding.getVariable("y") +", " + binding.getVariable("y").equals(20)); System.err.println(binding.getVariable("z") +", " + binding.getVariable("z").equals(30)); } }

運行結果如下:

Welcome to Groovy
10, true
20, true
30, true

2.使用GroovyScriptEngine腳本引擎加載Groovy腳本

GroovyScriptEngine從指定的位置(文件系統,URL,數據庫等等)加載Groovy腳本,並且隨著腳本變化可重新加載它們。和GroovyShell一樣,GroovyScriptEngine也可以傳進變量值返回腳本的計算結果。這樣我們可以把一些可用的計算公式或計算條件寫入Groovy腳本中來執行應用計算。當這些公式或計算條件變更時,我們可更方便地進行更改計算。

GroovyScriptEngineExample.java

import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;

public class GroovyScriptEngineExample {
    public static void main(String args[]) {
        try {
            String[] roots = new  String[]{".\\src\\sample\\"} ;//定義Groovy腳本引擎的根路徑
            GroovyScriptEngine engine = new GroovyScriptEngine(roots);
            Binding binding = new Binding();
            binding.setVariable("language", "Groovy");
            Object value = engine.run("SimpleScript.groovy", binding);
            assert value.equals("The End");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
SimpleScript.groovy
println "Welcome to $language"
return "The End"

運行結果如下:

Welcome to Groovy

3.使用GroovyClassLoader動態地載入Groovy的類

下例現示如何使用GroovyClassLoader加載Groovy類並且調用該類的一個方法。

GroovyClassLoaderExample.java

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;

public class GroovyClassLoaderExample {
    public static void main(String args[]) {
        try {
            GroovyClassLoader loader = new GroovyClassLoader();
            Class fileCreator = loader.parseClass(new File("src\\sample\\GroovySimpleFileCreator.groovy"));
            GroovyObject object = (GroovyObject) fileCreator.newInstance();
            object.invokeMethod("createFile", "D:\\temp\\emptyFile.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

GroovySimpleFileCreator.groovy

class GroovySimpleFileCreator {
    public createFile(String fileName){
        File file = new File(fileName);
        file.createNewFile();
    }
}

使用GroovyClassLoader另一種情景便是:存在一個Java接口和一個實現該Java接口的Groovy類。此時,可以通過GroovyClassLoader加載Groovy實現類到應用中,這樣就可以直接調用該接口的方法。

IFoo.java

public interface IFoo {
    Object run(Object foo);
}

InvokeGroovy.java

import groovy.lang.GroovyClassLoader;

public class InvokeGroovy {
    public static void main(String[] args) {
        ClassLoader cl = new InvokeGroovy().getClass().getClassLoader();
        GroovyClassLoader groovyCl = new GroovyClassLoader(cl);
        try {
            //從文件中讀取,將實現IFoo接口的groovy類寫在一個groovy文件中
            //Class groovyClass = groovyCl.parseClass(new File("./src/sample/Foo.groovy"));
            //直接使用Groovy字符串,也可以獲得正確結果
            Class groovyClass = groovyCl.parseClass("class Foo implements IFoo {public Object run(Object foo) {return 2+2>1}}");//這個返回true
            IFoo foo = (IFoo) groovyClass.newInstance();
            System.out.println(foo.run(new Integer(2)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行結果如下:

true

4.使用JAVA腳本API

Java SE 6 引入了對 Java Specification Request(JSR)223 的支持,JSR 223 旨在定義一個統一的規範,使得 Java 應用程序可以通過一套固定的接口與各種腳本引擎交互,從而達到在 Java 平臺上調用各種腳本語言的目的。每一個腳本引擎就是一個腳本解釋器,負責運行腳本,獲取運行結果。ScriptEngine 接口提供了許多 eval 函數的變體用來運行腳本,這個函數的功能就是獲取腳本輸入,運行腳本,最後返回輸出。

GroovyJSR223Example.java

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class GroovyJSR223Example {
    public static void main(String args[]) {
        try {
            ScriptEngineManager factory = new ScriptEngineManager();
            ScriptEngine engine = factory.getEngineByName("groovy");
            String HelloLanguage = "def hello(language) {return \"Hello $language\"}";
            engine.eval(HelloLanguage);
            Invocable inv = (Invocable) engine;
            Object[] params = {new String("Groovy")};
            Object result = inv.invokeFunction("hello", params);
            //assert result.equals("Hello Groovy");
            System.out.println(result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

運行結果如下:

Hello Groovy

參考:

[1] Java中運行動態腳本Groovy

[2] Java動態調用腳本語言Groovy,完善接口配置

[3] Java結合Groovy讓程序支持動態算法打賞

Java動態調用腳本語言Groovy