Java中不同类型的Groovy执行

时间:2012-12-07 16:45:33

标签: java scripting groovy

关于在java中使用Groovy,我有3个问题。他们都在一起,所以我只在这里创建一个问题。

1)有:GroovyClassLoader,GroovyShell,GroovyScriptEngine。但使用它们有什么区别?

例如,此代码:

static void runWithGroovyShell() throws Exception {
    new GroovyShell().parse(new File("test.groovy")).invokeMethod("hello_world", null);
}

static void runWithGroovyClassLoader() throws Exception {
    Class scriptClass = new GroovyClassLoader().parseClass(new File("test.groovy"));
    Object scriptInstance = scriptClass.newInstance();
    scriptClass.getDeclaredMethod("hello_world", new Class[]{}).invoke(scriptInstance, new Object[]{});
}

static void runWithGroovyScriptEngine() throws Exception {
    Class scriptClass = new GroovyScriptEngine(".").loadScriptByName("test.groovy");
    Object scriptInstance = scriptClass.newInstance();
    scriptClass.getDeclaredMethod("hello_world", new Class[]{}).invoke(scriptInstance, new Object[]{});
}

2)加载groovy脚本的最佳方法是什么,它以编译的形式保留在内存中,然后我可以在需要时调用该脚本中的函数到。

3)如何将我的java方法/类暴露给groovy脚本,以便在需要时可以调用它们?

1 个答案:

答案 0 :(得分:2)

方法2和3都返回解析的class作为回报。因此,一旦解析并成功加载,您就可以使用map将它们保存在内存中。

Class scriptClass = new GroovyClassLoader().parseClass(new File("test.groovy"));
map.put("test.groovy",scriptClass);

<强>更新

GroovyObject链接到groovy对象文档。

这也可以直接转换对象,因为GroovyObject和其他java类是无法区分的。

Object aScript = clazz.newInstance();
MyInterface myObject = (MyInterface) aScript;
myObject.interfaceMethod();
 //now here you can also cache the object if you want to

无法评论效率。但我想如果你把加载的类保存在内存中,一次解析就不会有太大的影响。

更新效率: 您应该使用GroovyScriptEngine,它在内部使用脚本缓存

以下是链接:Groovy Script Engine

否则你总是可以自己使用一些性能基准测试它,你会得到粗略的想法。例如:在三个不同的循环中使用所有三种方法编译groovy脚本,并查看哪些表现更好。尝试使用相同和不同的脚本,以某种方式查看缓存是否开始。

向SCRIPT传递参数的更新 Binding class将帮助您向脚本发送和从脚本发送参数。

Example Link

// setup binding
def binding = new Binding()
binding.a = 1
binding.setVariable('b', 2)
binding.c = 3
println binding.variables

// setup to capture standard out
def content = new StringWriter()
binding.out = new PrintWriter(content)

// evaluate the script
def ret = new GroovyShell(binding).evaluate('''
def c = 9
println 'a='+a
println 'b='+b
println 'c='+c 
retVal = a+b+c
a=3
b=2
c=1
''')

// validate the values
assert binding.a == 3
assert binding.getVariable('b') == 2
assert binding.c == 3 // binding does NOT apply to def'd variable
assert binding.retVal == 12 // local def of c applied NOT the binding!

println 'retVal='+binding.retVal
println binding.variables
println content.toString()