引入 Groovy 依赖
在 build.gralde 中:
dependencies {
// https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.5.9'
}
执行 groovy 脚本的几种方法
方法1
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class Demo {
public static void main(String[] args) {
Binding binding = new Binding();
// 绑定变量到 groovy 执行环境
binding.setVariable("foo", new Integer(2));
// 构建 groovy shell
GroovyShell shell = new GroovyShell(binding);
// 执行脚本
Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");
// 执行结果
System.out.printf("执行结果:%s, 类型: %s\n", value, value.getClass().getCanonicalName());
// 获取执行过程中的变量
System.out.printf("执行过程中的x变量:%s, 类型: %s\n", binding.getVariable("x"), binding.getVariable("x").getClass().getCanonicalName());
}
}
执行结果:
Hello World!
执行结果:20, 类型: java.lang.Integer
执行过程中的x变量:123, 类型: java.lang.Integer
方法2
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
public class Demo {
public static void main(String[] args) {
// 绑定变量到 groovy 执行环境
Binding binding = new Binding();
binding.setVariable("foo", new Integer(2));
// 构建 groovy script
GroovyShell shell = new GroovyShell();
Script script = shell.parse("println 'Hello World!'; x = 123; return foo * 10");
script.setBinding(binding); // 绑定
// 执行脚本
Object value = script.run();
// 执行结果
System.out.printf("执行结果:%s, 类型: %s\n", value, value.getClass().getCanonicalName());
// 获取执行过程中的变量
System.out.printf("执行过程中的x变量:%s, 类型: %s\n", binding.getVariable("x"), binding.getVariable("x").getClass().getCanonicalName());
}
}
执行结果:
Hello World!
执行结果:20, 类型: java.lang.Integer
执行过程中的x变量:123, 类型: java.lang.Integer
方法3
使用 InvokerHelper.createScript 创建脚本对象。
import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.runtime.InvokerHelper;
public class Demo {
public static void main(String[] args) {
// 绑定变量到 groovy 执行环境
Binding binding = new Binding();
binding.setVariable("foo", new Integer(2));
GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
Class scriptClass = groovyClassLoader.parseClass("println 'Hello World!'; x = 123; return foo * 10");
// 执行脚本
Object value = InvokerHelper.createScript(scriptClass, binding).run();
// 执行结果
System.out.printf("执行结果:%s, 类型: %s\n", value, value.getClass().getCanonicalName());
// 获取执行过程中的变量
System.out.printf("执行过程中的x变量:%s, 类型: %s\n", binding.getVariable("x"), binding.getVariable("x").getClass().getCanonicalName());
}
}
方法4
执行 groovy 文件。
todo
示例1:在 groovy 脚本中执行 java 定义的函数
示例:
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class Demo {
public static class Func {
public long add(long a, long b) {
return a+b;
}
}
public static void main(String[] args) {
Binding binding = new Binding();
binding.setVariable("func", new Func());
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("return func.add(1, 1)");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
}
}
执行结果:
执行结果:2, 类型:java.lang.Long
示例2:在 groovy 脚本中执行 java 定义的静态函数
也可以执行java 中定义的静态方法:
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class Demo {
public static class Func {
// 这是一个静态方法
public static long add(long a, long b) {
return a+b;
}
}
public static void main(String[] args) {
Binding binding = new Binding();
binding.setVariable("func", Func.class);
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("return func.add(1, 1)");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
}
}
示例3:传入上下文
Binding 本身也是一种上下文,但有时需要每一个java函数能感知到上下文,此时需要其他的实现方式。
传入上下文的方法有很多,比如作为函数参数,比如作为类的构造函数参数,比如放入 ThreadLocal 。
示例:
import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.GroovyShell;
import java.util.HashMap;
import java.util.Map;
public class Demo {
public static class Func {
private Map<String, Object> context;
// 上下文作为构造函数参数传入
public Func(Map<String, Object> context) {
this.context = context;
}
public long add(long a, long b) {
System.out.println("add 方法上下文: " + context);
return a+b;
}
}
public static void main(String[] args) {
// 构造上下文
Map<String, Object> context = new HashMap<>();
context.put("name", "lt");
Binding binding = new Binding();
binding.setVariable("func", new Func(context));
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("return func.add(1, 1)");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
}
}
执行结果:
add 方法上下文: {name=lt}
执行结果:2, 类型:java.lang.Long
示例4:闭包
groovy 有一个闭包的概念,类似 java 中的 lambda 。
示例:
import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.GroovyShell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Demo {
public static class Func {
// 过滤函数,第2个参数是闭包
public List<Integer> filter(List<Integer> list, Closure<Boolean> closure) {
return list.stream().filter(x -> {
return closure.call(x);
}).collect(Collectors.toList());
}
}
public static void main(String[] args) {
Binding binding = new Binding();
binding.setVariable("func", new Func());
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("return func.filter([-1,2,3,4], {x -> x > 0} )");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
}
}
执行结果:
执行结果:[2, 3, 4], 类型:java.util.ArrayList
示例5:在 Java 中定义一个 Groovy 闭包类
import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.GroovyShell;
public class Demo {
// 这是一个 groovy 闭包
public static class Add extends Closure<Long> {
public Add() {
super(null, null);
}
@Override
public Long call(Object... args) {
long result = 0;
for (Object obj : args) {
if (obj instanceof Integer) {
result = result + (Integer) obj;
continue;
}
if (obj instanceof Long) {
result = result + (Long) obj;
continue;
}
}
return result;
}
}
public static void main(String[] args) {
Binding binding = new Binding();
binding.setVariable("add", new Add());
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("return add(1,2,3)");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
}
}
执行结果:
执行结果:6, 类型:java.lang.Long
示例6:在 groovy 中修改 java 变量
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import java.util.Arrays;
import java.util.List;
public class Demo {
public static class Person {
public String name;
public int age;
public List<String> books;
public String getName() {
return name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", books=" + books +
'}';
}
}
public static void main(String[] args) {
Binding binding = new Binding();
Person person = new Person();
person.name = "lt";
person.age = 10;
person.books = Arrays.asList("book0", "book1");
System.out.println("修改前: " + person);
binding.setVariable("person", person);
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("println 'in groovy books : ' + person.books; person.books[1] = 'new book1';return person.name");
System.out.printf("执行结果:%s, 类型:%s\n", value, value.getClass().getCanonicalName());
System.out.println("修改后: " + person);
}
}
执行结果:
修改前: Person{name='lt', age=10, books=[book0, book1]}
in groovy books : [book0, book1]
执行结果:lt, 类型:java.lang.String
修改后: Person{name='lt', age=10, books=[book0, new book1]}
参考
- http://ifeve.com/embedding-groovy/