1
Groovy互操作说明
Groovy脚本有两种调用方式,一是作为普通脚本文件(.groovy),使用Groovy提供的命令行groovy或者通过类groovy.lang.GroovyShell来调用。二是作为普通的Java类文件(.class),用传统的方式来调用,这需要先使用groovyc把脚本文件编译成类文件,然后再使用java命令来调用。
2
Groovy脚本调用Groovy脚本
2.1
代码:
Test.groovy:
package
org.nick;
class
Test{
Test(){
t = new TestS();
t.a();
}
static void
main(String[] args){
t = new Test();
}
}
TestS.groovy:
package
org.nick;
class
TestS{
void
a(){
println("Hello
World");
}
}
2.2
使用groovy命令:
i.
说明:不可行。由于groovy没有提供指定classpath的参数,因此,当两个groovy脚本需要进行互相调用时,Test.groovy将不能找到他所需要的TestS.groovy的定义,因此,通过groovy命令,不能实现两个脚本间的直接调用。
2.3
使用GroovyShell:
i.
说明:可行。由于GroovyShell是一标准的Java类,因此,我们可以通过指定classpath,来找到所需的类。但这里有一个前提,被调用的脚本需要事先编译为.class文件。
ii.
实例:
<target
name="run" depends="init">
<java
classname="groovy.lang.GroovyShell">
<classpath
refid="run.path"/>
<arg
value="${src.dir}/org/nick/Test.groovy" />
</java>
</target>
注:classpath当中包含了GroovyShell所在的jar,和被调用脚本编译后类文件的目录。
2.4
使用java命令:
i.
说明:可行。由于所有的脚本文件都被编译为了.class文件,因此,我们可以像一般的情况那样,在脚本之间互相调用。
ii.
实例:
<java
classname="org.nick.Test">
<classpath
refid="run.path"/>
</java>
3
Groovy脚本调用Java代码
3.1
代码:
Test.groovy:
package
org.nick;
class
Test{
Test(){
b = new TestJ();
b.a();
}
static void
main(String[] args){
t = new Test();
}
}
TestJ.java:
package org.nick;
public class TestJ {
public
void a(){
System.out.println("Hello");
}
}
3.2
使用groovy命令:
i.
说明:理论不可行。原因同上,由于groovy不能指定其他类所在的位置,所以理论上不可行。但实际上groovy脚本内部是能够调用java.*等包中的Java类的,也就是说只要我们把我们自己写的Java类提前编译了,并放到classpath所指定的位置,我们就能使用groovy命令来实现Groovy脚本调用Java代码。
3.3
使用GroovyShell:
i.
说明:可行。理由同上。只要把Java文件提前编译了即可。
3.4
使用java命令:
i.
说明:可行。理由同上。
4
Java代码调用Groovy脚本
4.1
代码:
Groovy脚本:
package
org.nick;
for(it in
args)
println(it)
Groovy类:
package
org.nick;
class
Test{
void
a(name){
println("Hello
${name}");
}
}
4.2
使用GroovyShell调用Groovy脚本:
i.
说明:通过GroovyShell类,我们可以在Java程序代码中直接加载和运行Groovy脚本。而且,通过Binding类,我们还可以向Groovy脚本传递参数的值。
ii.
代码:
package org.nick;
public class GroovyTest {
public static void
main(String[] args) throws Exception{
Binding binding = new
Binding();
binding.setVariable("args",
new String[]{"aaa","bbb","ccc"});
GroovyShell shell = new
GroovyShell(binding);
Object obj =
shell.evaluate(new File("src/org/nick/Test.groovy"));
}
}
4.3
使用GroovyScriptEngine调用Groovy脚本:
i.
说明:GroovyScriptEngine是比GroovyShell更完整的一个方案,通过roots变量,我们指定了脚本文件所在的目录,然后在需要运行时,GroovyScriptEngine将根据roots中的变量查找并运行指定的脚本文件。同样,我们可以通过Binding类为脚本传入参数。另外,有一点很重要的就是,当我们所调用的脚本调用了另一脚本时,如果使用GroovyShell方式且被调用脚本未编译为Java类,那么将出现ClassNotFound错误,但如果使用GroovyScriptEngine,那么当一脚本调用另一脚本时,即使另一脚本未编译为Java类,但只要他出现在roots变量所指向的位置,GroovyScriptEngine也能找到该对应的脚本。
ii.
代码:
package org.nick;
public class GroovyTest {
public
static void main(String[] args) throws Exception {
String[]
roots = new String[] { "src/org/nick" };
GroovyScriptEngine
gse = new GroovyScriptEngine(roots);
Binding
binding = new Binding();
binding.setVariable("args",
new String[] { "aaa", "bbb", "ccc" });
gse.run("Test.groovy",
binding);
}
}
4.4
使用GroovyClassLoader加载Groovy类:
i.
说明:通过GroovyClassLoader我们可以像在Java代码当中那样,动态加载由Groovy脚本书写的类。并且通过对所装载的类进行实例化,我们可以以一种类似于反射的方式来调用其内部的方法。
ii.
代码:
package org.nick;
public class GroovyTest {
public
GroovyTest() {
try
{
ClassLoader
parent = getClass().getClassLoader();
GroovyClassLoader
loader = new GroovyClassLoader(parent);
Class
groovyClass = loader.parseClass(new File
("src/org/nick/Test.groovy"));
GroovyObject
groovyObject = (GroovyObject)
groovyClass.newInstance();
groovyObject.invokeMethod("a",new
Object[]{"aaa"});
}
catch (Exception e) {
e.printStackTrace();
}
}
public
static void main(String[] args) {
GroovyTest
t = new GroovyTest();
}
}