@(JAVA总结)

1. 场景描述

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

  1. 可以直接调用groovy脚本中的方法
  2. 能传递对象到groovy方法中,不仅仅是字符串
  3. 提供脚本缓存机制,不用每次调用脚本的时候,都到磁盘读取
  4. 修改groovy后能实时生效

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

2. 解决方案

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

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"); }

转载于:https://www.cnblogs.com/zhanying999666/p/10156179.html

Groovy小结:java调用Groovy方法并传递参数相关推荐

  1. js向jsf调用后台方法并传递参数

    使用p:remoteCommand来达到复杂的异步刷新取值 大家请注意,这个方法可以真正的解决在jsf中通过js调用后台bean方法并获取bean方法返回值的问题. 同样,首先我们要写两个jsf组件, ...

  2. java调用shell脚本并传递参数

    最近业务上需要java调用执行shell脚本进行一些业务处理,写了个demo,记录下. 主要代码 @RequestMapping("/copy/database")@Respons ...

  3. java 调用groovy脚本,实现多个sql按指定逻辑运行,可做报表预聚合

    java 调用groovy脚本,实现多个sql按指定逻辑运行,可做报表预聚合 1.引入pom <dependency><groupId>org.codehaus.groovy& ...

  4. java调用Groovy脚本

    一.使用 用 Groovy 的 GroovyClassLoader ,它会动态地加载一个脚本并执行它.GroovyClassLoader是一个Groovy定制的类装载器,负责解析加载Java类中用到的 ...

  5. 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 参考 Script#evaluate 方法 | 创建 Binding 对象并设置 args 参数 )

    文章目录 一.Groovy 类中调用 Groovy 脚本 1.参考 Script#evaluate 方法分析 Groovy 类中调用 Groovy 脚本 2.创建 Binding 对象并设置 args ...

  6. 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 创建 GroovyShell 对象并执行 Groovy 脚本 | 完整代码示例 )

    文章目录 一.Groovy 类中调用 Groovy 脚本 1.创建 GroovyShell 对象并执行 Groovy 脚本 2.代码示例 二.完整代码示例 1.调用者 Groovy 脚本的类 2.被调 ...

  7. Java 调用 Python 方法学习笔记

    文章转载自: 作者:IT_xiao_bai                         来源:CSDN                         原文:https://blog.csdn.n ...

  8. Android和JS之间互相调用方法并传递参数

    场景 Android中使用WebView加载本地html并支持运行JS代码和支持缩放: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/detail ...

  9. java 调用祖父方法_在Java中调用祖父母方法:您不能

    java 调用祖父方法 在文章保护的重点中,我详细介绍了"受保护"如何扩展"包私有"访问. 我在那儿写道: 你能做的是 覆盖子类中的方法或 使用关键字super ...

最新文章

  1. python有趣代码-一个有意思的 Python 训练项目集
  2. 你真的知道怎么实现一个延迟队列吗 ?
  3. 【最简解法】1048 Find Coins (25 分)_18行代码AC
  4. SpringAOP xml 方式和注解简单实现日志处理
  5. 计算机考研初试复试比例,考研初试400多分,16人都被刷,计算机专业报考人太多,报应来了...
  6. 首批华为鸿蒙系统课程开发者
  7. JAVA设计模式 - 工厂方法模式
  8. XLSTransformer 导出Excel数据
  9. 软件测试经典面试题30道
  10. 联想用u盘重装系统步骤_联想u盘重装win10系统详细图文教程
  11. CDN加速解决VSCode下载速度慢的问题
  12. Torch not compiled with CUDA enabled报错的解决办法
  13. win10如何设置计算机网络访问,win10系统设置允许或拒绝从网络中访问本地电脑的操作方法...
  14. 手把手教你接入支付宝支付
  15. conda:未找到命令
  16. plc云网关与串口服务器区别,plc智能网关和传统工业路由器有什么区别
  17. SQL AND OR 运算符的用法
  18. UGI九宫格sliced显示问题
  19. PDF软件推荐——Sumatra PDF - imsoft.cnblogs
  20. 点滴记录,与技术无关

热门文章

  1. Android实战——Activity超详细学习笔记
  2. python小爬虫—获取学校教务处成绩
  3. libcurl 发送邮件_libcurl smtp发送邮件附件大小限制问题
  4. tomcat启动成功 未加载项目_智云CRM项目启动大会在深圳成功召开
  5. vue一个页面用两个以上页面 时时刷新
  6. linux系统支持什么格式的软件吗,UOS系统支持什么样的软件包格式:其实Deb,Rpm,Tar.gz源码包都行...
  7. 华为交换机带宽不足会丢包吗_华为岳伟:品质家宽,释放F5G网络体验红利
  8. 盗墓笔记android,盗墓笔记手游下载
  9. php根据图片地址获取图片原始高宽,Js获取图片原始宽高的实现代码
  10. python培训内幕_刚刚,Python 内幕被爆出!老码农:没控制住,心态已崩!