我是做工作流項目的,工作流中各個模板引擎都需要要執行一個動態業務,這些動態業務有多種實現方式,最常用的就是用戶自己寫一段腳本文件,然后工作流引擎執行到這里的時候,運行這個腳本文件。
這個運行腳本文件的功能最初項目組是用ScriptEngineManager實現的。要求用戶提供一個實現業務的jar,並寫js腳本,腳本里動態地調用java內置在js引擎里的幾個函數,這幾個函數就是動態地調用jar里面的業務函數。
但是這樣做太不方便,一是js無法調用java代碼,只能預置java函數,或者通過預置的java函數反射其他業務函數。同時js語法對於java程序員也太晦澀了,作為java程序員,很多對js語法不夠了解,甚至是誤解的。
於是js這個方式我們就棄用了,現在准備使用Groovy這門語言來做腳本。
Groovy相信java開發人員都聽說過,畢竟是java的兄弟語言,他和java一樣都是基於jvm這個中間件的語言,關系可以類比c#.net和vb.net。和Groovy相同的基於jvm的語言也有很多,這里就不展開了。
那么使用Groovy有什么好處呢?
1.首先需求是要求使用動態腳本語言,調用java寫的類庫,因此語言最好是動態的,這樣可以寫得更少的代碼,對於腳本也有來說代碼長度至關重要。Groovy就是這樣一個動態語言,有閉包以及其他動態語言中的特性。這些特性我不是特別看重,主要是他的集合對象調用非常簡單,[]可以視為list對象,{}可以視為map對象,同時是弱類型的,你不需要像使用java一樣在類型轉換上花很多時間。這些對於腳本語言來說太重要了。畢竟腳本語言只是組織和調用java寫的業務,自己不做業務,所以不需要太好的可維護性,但是需要足夠靈活能夠簡單高效地調用業務函數。
2.Groovy幾乎支持java的所有語法,你可以把他直接當做java來用,這樣對於java工程師而言無疑是福音,如果你拒絕使用Groovy的動態特性,你完全可以只寫java代碼,完全把他當java來用。
3.Groovy能直接調用java現有的類,也就是說你可以直接使用某個jar提供的類庫,這一點對於我們來說太重要了,直接new業務函數類,就可以調用jar里面的業務接口了。
為了測試Groovy是否能完成以上需求,我做了一個測試demo。
首先定義一個java類,充當業務jar。
public class JavaFunction { public static int i = 0; public String run() { return "運行了java代碼"; } }
然后直接GroovyShell測試腳本
import groovy.lang.Binding; import groovy.lang.GroovyShell; public class GroovyScriptEngineTest { public static void main(String[] args) throws Exception { Binding binding = new Binding(); binding.setVariable("javaFunction", new JavaFunction()); GroovyShell gs = new GroovyShell(binding); Object value = gs.evaluate( //可以引入java類 "import com.zrsoft.groovyScriptEngineTest.JavaFunction;" + "println 'Groovy可以直接import當前classpath里的類!';" //可以寫Groovy語法的代碼。Groovy是動態語言,比java適合寫腳本 + "println '運行了Groovy代碼!';" //可以使用java風格的Groovy,其實就是java代碼,因為Groovy支持java + "String javaCode = \"運行了Java風格的Groovy代碼!\";" + "System.out.println(javaCode);" //可以直接創建java自定義的對象 + "JavaFunction newJavaFunction = new JavaFunction();" + "println \"在Groovy引擎里創建java對象,並\" + newJavaFunction.run();" //可以調用腳本預設的java對象 + "return javaFunction.run();"); System.out.println("為GroovyShell預設java對象,並在Groovy里" + value + ",同時證明Groovy可以返回變量給java。"); } }
以上測試全部通過
Groovy可以直接import當前classpath里的類! 運行了Groovy代碼! 運行了Java風格的Groovy代碼! 在Groovy引擎里創建java對象,並運行了java代碼 為GroovyShell預設java對象,並在Groovy里運行了java代碼,同時證明Groovy可以返回變量給java。
當然以上測試完成,還不足以讓我們確定使用Groovy做腳本方案可行,運行性能和運行后內存釋放情況還需進一步考察。