New*_*ger 5 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[]{});
}
Run Code Online (Sandbox Code Playgroud)
2)加载groovy脚本的最佳方法是什么,以便它以编译的形式保留在内存中,然后我可以在需要时调用该脚本中的函数.
3)如何将我的java方法/类暴露给groovy脚本,以便它可以在需要时调用它们?
方法2和3都返回解析class后的结果。因此,map一旦解析并成功加载它们,您就可以使用 a 将它们保留在内存中。
Class scriptClass = new GroovyClassLoader().parseClass(new File("test.groovy"));
map.put("test.groovy",scriptClass);
Run Code Online (Sandbox Code Playgroud)
更新:
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
Run Code Online (Sandbox Code Playgroud)
无法评论效率。但我想如果你将加载的类保留在内存中,一次解析不会造成太大伤害。
更新为了提高效率:您应该使用GroovyScriptEngine,它在内部使用脚本缓存。
这是链接:Groovy 脚本引擎
否则,您始终可以自己使用一些性能基准测试它,并且您会得到粗略的想法。例如:在三个不同的循环中使用所有三种方法编译 groovy 脚本,看看哪个性能更好。尝试使用相同和不同的脚本,看看缓存是否以某种方式启动。
向脚本传递参数和从脚本传递参数的更新 绑定类将帮助您向脚本发送参数或从脚本传递参数。
// 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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2456 次 |
| 最近记录: |