295
技術社區[雲棲]
嵌入Groovy
Groovy就其本身而言,在不同的場景下都算是一門非常不錯的編程語言,特別是在與Java混用的環境下,Groovy顯得更加強大。出於這種考慮,Groovy被設計成非常輕量級,並且易於嵌入到任何Java應用係統中。
目前主要有3種方法將Groovy與Java集成起來,細節會在下文中討論。
還有一種可選方案是,如果你確實需要使用其他腳本語言,可以利用Bean Scripting Framework將任何腳本語言集成到你的Java代碼中(雖然我們難以想象這麼做的原因)。
利用shell執行腳本或者表達式
你可以使用GroovyShell執行Groovy中的任何表達式或者腳本。
GroovyShell允許你通過Binding對象傳進和傳出變量。
// call groovy expressions from Java code Binding binding = new Binding(); binding.setVariable("foo", new Integer(2)); GroovyShell shell = new GroovyShell(binding); Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10"); assert value.equals(new Integer(20)); assert binding.getVariable("x").equals(new Integer(123));
利用一個常用基類執行腳本
將Groovy腳本繼承自一個你選擇的基類,之後便可以訪問腳本的常規方法,這種做法往往非常有用。可以通過在編譯配置中設置腳本基類屬性,並將新的編譯配置傳遞給shell完成這一操作。
class ScriptBaseTest { @Test void extend_groovy_script() { def configuration = new CompilerConfiguration() configuration.setScriptBaseClass("ScriptBaseTestScript") def shell = new GroovyShell(this.class.classLoader, new Binding(), configuration) assertEquals shell.evaluate("foo()"), "this is foo" } } abstract class ScriptBaseTestScript extends Script { def foo() { "this is foo" } }
在Java中動態加載和運行Groovy腳本
你可以在Java代碼中直接使用GroovyClassLoader動態地加載和執行Groovy類。Java代碼如下:
ClassLoader parent = getClass().getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); Class groovyClass = loader.parseClass(new File("src/test/groovy/script/HelloWorld.groovy")); // let's call some method on an instance GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); Object[] args = {}; groovyObject.invokeMethod("run", args);
如果你想在Java裏使用一個接口,但是接口的實現在Groovy腳本中,可以這樣:
GroovyClassLoader gcl = new GroovyClassLoader(); Class clazz = gcl.parseClass(myStringwithGroovyClassSource, "SomeName.groovy"); Object aScript = clazz.newInstance(); MyInterface myObject = (MyInterface) aScript; myObject.interfaceMethod(); ...
如果這個Groovy類實現了接口MyInterface,這麼做是沒有問題的。從現在開始myObject可以像其他實現了MyInterface接口的類一樣使用。
需要注意的一點是,parseClass 方法會從你的字符串文件名中創建一個對象。另一個gcl.parseClass的用法是:
Class clazz = gcl.parseClass(new File("SomeName.groovy");
完整的例子如下所示:
TestInterface.java public interface TestInterface { public void printIt(); } Tester.groovy public class Tester implements TestInterface { public void printIt() { println "this is in the test class"; } } TestClass.java -- inside of a method String fileName = "Tester.groovy"; GroovyClassLoader gcl = new GroovyClassLoader(); Class clazz = gcl.parseClass(new File(fileName)); Object aScript = clazz.newInstance(); TestInterface ifc = (TestInterface) aScript; ifc.printIt();
請注意,所有的異常處理都已經被移除了,你不必在Java類中關心這個。實際上我會在一個工具類中完成Groovy的接口調用。
GroovyScriptEngine
如果開發人員想把Groovy腳本嵌入到服務器內,並且在腳本變更之後也能夠重新加載,GroovyScriptEngine是一個主要的解決方案。你可以使用一個CLASSPATH集合(url或者路徑名稱)初始化GroovyScriptEngine,之後便可以執行這些路徑中的Groovy腳本了。GroovyScriptEngine同樣可以跟蹤相互依賴的腳本,如果其中一個被依賴的腳本發生變更,則整個腳本樹都會被重新編譯和加載。
此外,每次腳本的執行,還可以利用一個腳本可以訪問的包含了最新參數的Binding對象傳遞信息。例子如下:
/my/groovy/script/path/hello.groovy: output = "Hello, ${input}!" import groovy.lang.Binding; import groovy.util.GroovyScriptEngine; String[] roots = new String[] { "/my/groovy/script/path" }; GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding = new Binding(); binding.setVariable("input", "world"); gse.run("hello.groovy", binding); System.out.println(binding.getVariable("output"));
輸出是“Hello, world!”。
在Java應用程序中嵌入Groovy控製台
可以將一個交互式Groovy解釋器嵌入到運行中的應用程序中,以便調試和測試。請參考例子Embedding a Groovy Console in a Java Server Application,這是一個包含了示例代碼的教程。將Groovy作為腳本語言嵌入到應用程序中的例子也可以參考Integrating Groovy in an application – a success story。
運行時的依賴
你可以把groovy-all-x.y.z.jar拷貝到Groovy的安裝目錄中,也可以從Gradle / Maven / Ant+Ivy中查找相應的包的路徑執行構建。關於如何獲取Groovy,請查看download小節。
最後更新:2017-05-23 09:31:44
上一篇:
線程安全與共享資源
下一篇:
采用Java 8中Lambda表達式和默認方法的模板方法模式
NSString中的stringByReplacingOccurrencesOfString
如何在 CentOS 7 中在 HHVM 和 Nginx 之上安裝 WordPress
企業建設H5響應式網站的5大好處
基礎架構體係中間件學習
動態規劃-hdoj-4832-百度之星2014初賽第二場
從0到1構建大數據生態係列1:數據蠻荒中的拓荒之舉
進程通信係列-主程序
???????????????Elasticsearch????????????2????????????2.4.2???????????????????????????-??????-????????????-?????????
要做一個公司網站,前提必須了解什麼?
16進製字符-->10進製數字