嵌入Groovy

简介:

Groovy就其本身而言,在不同的场景下都算是一门非常不错的编程语言,特别是在与Java混用的环境下,Groovy显得更加强大。出于这种考虑,Groovy被设计成非常轻量级,并且易于嵌入到任何Java应用系统中。

目前主要有3种方法将Groovy与Java集成起来,细节会在下文中讨论。

还有一种可选方案是,如果你确实需要使用其他脚本语言,可以利用Bean Scripting Framework将任何脚本语言集成到你的Java代码中(虽然我们难以想象这么做的原因)。

利用shell执行脚本或者表达式

你可以使用GroovyShell执行Groovy中的任何表达式或者脚本。

GroovyShell允许你通过Binding对象传进和传出变量。

// call groovy expressions from Java code
Binding binding = new Binding();

binding.setVariable("foo", new Integer(2));

GroovyShell shell = new GroovyShell(binding);

Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");

assert value.equals(new Integer(20));

assert binding.getVariable("x").equals(new Integer(123));

利用一个常用基类执行脚本

将Groovy脚本继承自一个你选择的基类,之后便可以访问脚本的常规方法,这种做法往往非常有用。可以通过在编译配置中设置脚本基类属性,并将新的编译配置传递给shell完成这一操作。

class ScriptBaseTest {

    @Test void extend_groovy_script() {

        def configuration = new CompilerConfiguration()

        configuration.setScriptBaseClass("ScriptBaseTestScript")

        def shell = new GroovyShell(this.class.classLoader, new Binding(), configuration)

        assertEquals shell.evaluate("foo()"), "this is foo"

    }

}

abstract class ScriptBaseTestScript extends Script {

    def foo() {

        "this is foo"

    }

}

在Java中动态加载和运行Groovy脚本

你可以在Java代码中直接使用GroovyClassLoader动态地加载和执行Groovy类。Java代码如下:

ClassLoader parent = getClass().getClassLoader(); 

GroovyClassLoader loader = new GroovyClassLoader(parent); 

Class groovyClass = loader.parseClass(new File("src/test/groovy/script/HelloWorld.groovy")); 

// let's call some method on an instance
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); 

Object[] args = {}; 

groovyObject.invokeMethod("run", args);

如果你想在Java里使用一个接口,但是接口的实现在Groovy脚本中,可以这样:

GroovyClassLoader gcl = new GroovyClassLoader(); 

Class clazz = gcl.parseClass(myStringwithGroovyClassSource, "SomeName.groovy"); 

Object aScript = clazz.newInstance(); 

MyInterface myObject = (MyInterface) aScript; 

myObject.interfaceMethod(); 

...

如果这个Groovy类实现了接口MyInterface,这么做是没有问题的。从现在开始myObject可以像其他实现了MyInterface接口的类一样使用。

需要注意的一点是,parseClass 方法会从你的字符串文件名中创建一个对象。另一个gcl.parseClass的用法是:

Class clazz = gcl.parseClass(new File("SomeName.groovy");

完整的例子如下所示:

TestInterface.java 

public interface TestInterface {

    public void printIt(); 

}

Tester.groovy 

public class Tester implements TestInterface { 

    public void printIt() { 

        println "this is in the test class"; 

    }

}

TestClass.java -- inside of a method 

String fileName = "Tester.groovy"; 

GroovyClassLoader gcl = new GroovyClassLoader(); 

Class clazz = gcl.parseClass(new File(fileName)); 

Object aScript = clazz.newInstance(); 

TestInterface ifc = (TestInterface) aScript; 

ifc.printIt();

请注意,所有的异常处理都已经被移除了,你不必在Java类中关心这个。实际上我会在一个工具类中完成Groovy的接口调用。

GroovyScriptEngine

如果开发人员想把Groovy脚本嵌入到服务器内,并且在脚本变更之后也能够重新加载,GroovyScriptEngine是一个主要的解决方案。你可以使用一个CLASSPATH集合(url或者路径名称)初始化GroovyScriptEngine,之后便可以执行这些路径中的Groovy脚本了。GroovyScriptEngine同样可以跟踪相互依赖的脚本,如果其中一个被依赖的脚本发生变更,则整个脚本树都会被重新编译和加载。

此外,每次脚本的执行,还可以利用一个脚本可以访问的包含了最新参数的Binding对象传递信息。例子如下:

/my/groovy/script/path/hello.groovy:

output = "Hello, ${input}!"

import groovy.lang.Binding; 

import groovy.util.GroovyScriptEngine; 

String[] roots = new String[] { "/my/groovy/script/path" }; 

GroovyScriptEngine gse = new GroovyScriptEngine(roots); 

Binding binding = new Binding(); binding.setVariable("input", "world"); 

gse.run("hello.groovy", binding); System.out.println(binding.getVariable("output"));

输出是“Hello, world!”。

在Java应用程序中嵌入Groovy控制台

可以将一个交互式Groovy解释器嵌入到运行中的应用程序中,以便调试和测试。请参考例子Embedding a Groovy Console in a Java Server Application,这是一个包含了示例代码的教程。将Groovy作为脚本语言嵌入到应用程序中的例子也可以参考Integrating Groovy in an application – a success story

运行时的依赖

你可以把groovy-all-x.y.z.jar拷贝到Groovy的安装目录中,也可以从Gradle / Maven / Ant+Ivy中查找相应的包的路径执行构建。关于如何获取Groovy,请查看download小节。

相关文章
|
Java
【Groovy】Groovy 动态语言特性 ( Groovy 语言与 Java 语言执行效率对比 | 以动态特性编译的 Groovy 类 | 以静态特性编译的 Groovy 类 )
【Groovy】Groovy 动态语言特性 ( Groovy 语言与 Java 语言执行效率对比 | 以动态特性编译的 Groovy 类 | 以静态特性编译的 Groovy 类 )
232 0
|
缓存 安全 搜索推荐
Groovy脚本高级特征总结
合理的使用脚本特征功能,可以大大提高程序的灵活性,这非常适合做一些补丁功能,或者个性化极强的功能,比如促销活动,这个活动规则会经常的变动,因此,如果不借助某种机制,当促销规则发生变化时,则需要重新进行编码调整并发布程序,这样的程序维护起来过于麻烦。
1309 0
 Groovy脚本高级特征总结
|
JSON Java C#
Groovy核心语法总结
Groovy是一种基于JVM,功能强大、类型可选,动态的、可与Java无缝衔接的编程语言。Groovy语法简洁、易于学习,可以大大提高开发人员的工作效率,可为Java程序添加强大的功能,包括脚本功能、特定领域的语言编写、运行时和编译时元编程以及函数式编程。本文将快速介绍核心语法,让读者快速入门。
1185 0
 Groovy核心语法总结
|
自然语言处理 Java
《领域特定语言》一1.5使用代码生成
本节书摘来自华章出版社《领域特定语言》一书中的第1章,第1.5节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1300 0

热门文章

最新文章