我是做工作流项目的,工作流中各个模板引擎都需要要执行一个动态业务,这些动态业务有多种实现方式,最常用的就是用户自己写一段脚本文件,然后工作流引擎执行到这里的时候,运行这个脚本文件。
这个运行脚本文件的功能最初项目组是用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做脚本方案可行,运行性能和运行后内存释放情况还需进一步考察。