首页 文章

Java中不同类型的Groovy执行

提问于
浏览
5

关于在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 回答

  • 2

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

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

    UPDATE:

    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
    

    不能评论效率 . 但我想如果你把加载的类保存在内存中,一次解析不会伤害太多 .

    UPDATE For efficiency :你应该使用 GroovyScriptEngine ,它在内部使用 script caching .

    这是链接:Groovy Script Engine

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

    UPDATE FOR PASSING PARAMS TO AND FROM 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()
    

相关问题