1. 程式人生 > >Groovy嵌入Java程式碼

Groovy嵌入Java程式碼

1、通過GroovyShell來實現:

        Binding binding = new Binding();
        GroovyShell shell = new GroovyShell(binding);
        Object value = shell.evaluate("println 'Hello World!'; return \"ret\"");
        System.out.println(value);

Binding用來設定指令碼中用到的引數。在用GroovyShell來執行的時候,每次都會根據文字編譯成Class,這樣有兩個問題:

a、在編譯程式碼上消耗的時間遠大於指令碼執行的時間。

b、生成的Class太多的話會導致FULL GC,輕則系統變慢,重則OMM。

2、通過GroovyClassLoader來實現:

        GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
        File sourceFile = new File("D:\\GroovyShell.txt");
        Class groovyClass = classLoader.parseClass(new GroovyCodeSource(sourceFile));
        System.out.println(groovyClass);

        GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
        System.out.println(groovyObject.invokeMethod("sayHello", null));

使用這種方式時,如果GroovyShell中的程式碼發生了改變,classLoader.parseClass載入的類還是原來的(在GroovyClassLoader中做了快取),如果不想要這種效果就在GroovyCodeSource中設定cache = false。在GroovyShell.txt中儲存的內容如下:

class GroovyShell {
    public String sayHello(){
        return 'hello world!';
    }
}

3、通過GroovyScriptEngine來執行指令碼:

        String[] roots = new String[]{"D:\\"};
        GroovyScriptEngine gse = new GroovyScriptEngine(roots);
        Binding binding = new Binding();
        gse.run("GroovyShell.txt", binding);
在GroovyShell.txt中的內容為:
print "hello world!"

GroovyScriptEngine會監控一個目錄,如果目錄中的檔案發生變化時,再載入到的Class為新的內容,否則為老的Class(而不是每次都編譯成新的Class)。