java 嵌入groovy_Groovy小结:java调用Groovy方法并传递参数

@(JAVA总结)

1. 场景描述

在网上查了资料发现,java有三种方式调用groovy脚本。但是真正在实际的服务器环境中,嵌入groovy脚本往往需要满足下面的条件:

可以直接调用groovy脚本中的方法

能传递对象到groovy方法中,不仅仅是字符串

提供脚本缓存机制,不用每次调用脚本的时候,都到磁盘读取

修改groovy后能实时生效

只有满足了上面的这些要求,才能安心的将其嵌入到现有的Java后台服务中。下面就来具体探讨下具体实现的步骤。

2. 解决方案

其实,GroovyScriptEngine类就已经提供了上面所说的功能。主要使用GroovyScriptEngine.loadScriptByName来读取脚本,loadScriptByName方法内部提供了缓存功能,在读取groovy脚本的时候,会优先从缓存中读取,如果缓存中没有的话,才去读取脚本,如下:

1449497426219.png

2.1 相关测试类和脚本

在后面的测试后,会用到下面的java类和groovy脚本。

2.1.1 测试类Person.java

该类用于测试传递Java对象到Groovy脚本中

public class Person {

public String name;

public String address;

public Integer age;

public Person(String name, String addr, Integer age){

this.name = name;

this.address = addr;

this.age = age;

}

public String toString(){

return String.format("[Person: name:%s, address:%s, age:%s]", name,address, age);

}

}

2.1.2 测试脚本hello2.groovy

下面脚本中的两个方法用于测试方法的无参调用和带参调用

def helloWithoutParam(){

println "start to call helloWithoutParam!"

return "success, helloWithoutParam";

}

def helloWithParam(person, id){

println "start to call helloWithParam, param{person:" + person + ", id:" + id + "}";

return "success, helloWithParam";

}

2.2 java调用Groovy脚本方法(无参)

public static void testGroovy2(){

try {

Class scriptClass = groovyScriptEngine.loadScriptByName("hello2.groovy");

GroovyObject scriptInstance = (GroovyObject)scriptClass.newInstance();

Object ret = scriptInstance.invokeMethod("helloWithoutParam", null);

System.out.println("testGroovy2:" + ret);

} catch (Exception e) {

e.printStackTrace();

System.out.println("Exception e="+e.toString());

}

}

执行结果:start to call helloWithoutParam!testGroovy2: success, helloWithoutParam

2.3 java调用Groovy脚本方法(带参)

@SuppressWarnings({ "rawtypes" })

public static void testGroovy3(){

try {

Person person = new Person("wchi", "nanjing", 30);

Class scriptClass = groovyScriptEngine.loadScriptByName("hello2.groovy");

GroovyObject scriptInstance = (GroovyObject)scriptClass.newInstance();

Object ret = scriptInstance.invokeMethod("helloWithParam", new Object[]{person,"lxi"});

System.out.println("testGroovy3:" + ret);

} catch (Exception e) {

e.printStackTrace();

System.out.println("Exception e="+e.toString());

}

}

返回结果:start to call helloWithParam, param{person:[Person: name:wchi, address:nanjing, age:30], id:lxi}testGroovy3: success, helloWithParam

2.4 封装的公用类

可以将上面的代码封装成公用类,这样就方便很多,如下:

public class GroovyCommonUtil {

private static final Logger log = LoggerFactory.getLogger(GroovyCommonUtil.class);

//该变量用于指明groovy脚本所在的父目录

static String root[]=new String[]{"bin/groovy/"};

static GroovyScriptEngine groovyScriptEngine;

static{

try {

groovyScriptEngine=new GroovyScriptEngine(root);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 用于调用指定Groovy脚本中的指定方法

* @param scriptName 脚本名称

* @param methodName 方法名称

* @param params 方法参数

* @return

*/

@SuppressWarnings({ "rawtypes"})

public Object invokeMethod(String scriptName, String methodName, Object... params) throws Exception{

Object ret = null;

Class scriptClass = null;

GroovyObject scriptInstance = null;

try {

scriptClass = groovyScriptEngine.loadScriptByName(scriptName);

scriptInstance = (GroovyObject)scriptClass.newInstance();

} catch (ResourceException | ScriptException | InstantiationException | IllegalAccessException e1) {

log.warn("加载脚本["+scriptName+"]出现异常", e1);

throw new Exception("加载脚本"+scriptName+"失败");

}

try {

ret = (String)scriptInstance.invokeMethod(methodName, params);

} catch (IllegalArgumentException e) {

log.warn("执行方法" + methodName + "参数出现异常, 参数为" + params, e);

throw new Exception("调用方法[" + methodName + "]失败,因参数不合法");

} catch(Exception e){

log.warn("执行方法" + methodName + "出现异常", e);

throw new Exception("调用方法[" + methodName + "]失败");

}

return ret;

}

使用上面的公用类,改写的测试代码如下:

/**

* 测试没有参数的方法调用

*/

public static void testGroovyWithoutParam(){

String result = (String)GroovyCommonUtil.invokeMethod("hello2.groovy", "helloWithoutParam");

System.out.println("testGroovy4: " + result + "\n");

}

/**

* 测试携带参数的方法调用

*/

public static void testGroovyWithParam(){

Person person = new Person("wchi", "nanjing", 30);

String result = (String)GroovyCommonUtil.invokeMethod("hello2.groovy", "helloWithParam", person, "testGroovy4");

System.out.println("testGroovy4: " + result + "\n");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值