详解Java执行groovy脚本的两种方式
作者:蒲公英不是梦 发布时间:2021-05-28 09:23:27
标签:Java,groovy,脚本
记录Java
执行groovy
脚本的两种方式,简单粗暴:
一种是通过脚本引擎ScriptEngine
提供的eval(String)
方法执行脚本内容;一种是执行groovy
脚本;
二者都通过Invocable
来传递参数并获取执行结果;
Invocable:脚本引擎的解释器接口,提供invokeFunction
和invokeMethod
两种传递参数并获取执行结果的方法,Java JDK API文档解释如下:
invokeFunction:
invokeMethod:
以下为案例:
引入依赖
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.2.74</version>
</dependency>
定义脚本内容并执行
public void testByFunction(){
// 初始化Bindings
Bindings bindings = engine.createBindings();
// 绑定参数
bindings.put("date", new Date());
final String name = "groovy";
// 定义groovy脚本中执行方法的名称
final String scriptName = "execute";
// 定义groovy脚本内容
final String scriptContent = "def " + scriptName +"(name){" +
" println(\"now dateTime is: ${date.getTime()}\");" +
" println(\"my name is $name\");" +
" return date.getTime() > 0;" +
"}";
try {
// 执行脚本
engine.eval(scriptContent, bindings);
// 获取执行结果
Invocable invocable = (Invocable) engine;
Boolean flag = (Boolean) invocable.invokeFunction(scriptName, name);
System.out.println("---------------------------------------");
System.out.println("result is: " + flag);
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
运行结果:
invokeFunction
方法的第一个参数为脚本的函数名称,把scriptName
拎出来通过创建String
对象再赋值进去,方便你看懂函数名称到底是哪个;scriptContent
中${date.getTime()}
与$name
的意思一样,grovvy
中的字符串可以识别${}
和$
占位符;bindings
绑定参数与invokeFunction
方法的第二个参数的区别是,前者是脚本内全局的,而后者是定义在函数内的;
例如把脚本内容定义为这样:
执行结果就是这样了:
实例化脚本对象并执行
public void testByMethod(){
try {
// 初始化groovy脚本对象
final TestGroovy testGroovy = new TestGroovy();
// 定义groovy脚本中执行方法的名称
final String scriptName = "execute";
// 定义参数
final Date arg_1 = new Date();
final String arg_2 = "groovy";
// 执行脚本并获取结果
Invocable invocable = (Invocable) engine;
Boolean flag = (Boolean) invocable.invokeMethod(testGroovy, scriptName, arg_1, arg_2);
System.out.println("---------------------------------------");
System.out.println("result is: " + flag);
} catch (ScriptException |NoSuchMethodException e) {
e.printStackTrace();
}
}
TestGroovy.groovy脚本内容:
package com.dandelion.groovy
class TestGroovy {
static def execute(Date date, String name){
println("now dateTime is: ${date.getTime()}");
println("my name is $name");
return date.getTime() < 0;
}
}
运行结果:
invokeMethod
方法的第一个参数是脚本对象,第二个参数是脚本中的函数名称,之后为绑定的参数;
源码:
package com.dandelion.test;
import com.dandelion.groovy.TestGroovy;
import javax.script.*;
import java.util.Date;
/**
* ================================
* 测试groovy脚本的执行方式
* @Author Him
* @Date 2021-04-21
* @Time 01:12
* ================================
*/
public class TestScriptEngine {
// 查找并创建指定脚本引擎
private ScriptEngine engine = new ScriptEngineManager().getEngineByName("groovy");
public void testByFunction(){
// 初始化Bindings
Bindings bindings = engine.createBindings();
// 绑定参数
bindings.put("date", new Date());
// 定义groovy脚本中执行方法的名称
final String scriptName = "execute";
// 定义groovy脚本内容
final String scriptContent = "def " + scriptName +"(){" +
" println(\"now dateTime is: ${date.getTime()}\");" +
" return date.getTime() > 0;" +
"}";
try {
// 执行脚本
engine.eval(scriptContent, bindings);
// 获取执行结果
Invocable invocable = (Invocable) engine;
Boolean flag = (Boolean) invocable.invokeFunction(scriptName);
System.out.println("---------------------------------------");
System.out.println("result is: " + flag);
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
public void testByMethod(){
try {
// 初始化groovy脚本对象
final TestGroovy testGroovy = new TestGroovy();
// 定义groovy脚本中执行方法的名称
final String scriptName = "execute";
// 定义参数
final Date arg_1 = new Date();
final String arg_2 = "groovy";
// 执行脚本并获取结果
Invocable invocable = (Invocable) engine;
Boolean flag = (Boolean) invocable.invokeMethod(testGroovy, scriptName, arg_1, arg_2);
System.out.println("---------------------------------------");
System.out.println("result is: " + flag);
} catch (ScriptException |NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestScriptEngine engine = new TestScriptEngine();
engine.testByFunction();
}
}
来源:https://www.cnblogs.com/dandelion200/p/14683609.html
0
投稿
猜你喜欢
- 登陆的时候,发现输入账号的不同大小写竟然能够登陆。Mybatis查询代码如下<select id="selectById&q
- 一、java发展史1.java之父:詹姆斯·高家林2.关键时间点:1996年Java(1.0)发布,2004年Java(5.0)发扬光大,2
- 1.导入jar包: <!--jmsTemplate--> <dependency> <
- C#的System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能。包括了.NET下的非泛型集合类以及非
- 递归算法设计的基本思想是:对于一个复杂的问题,把原问题分解为若干个相对简单类同的子问题,继续下去直到子问题简单到能够直接求解,也就是说到了递
- 一、AtomicReference 基本使用我们这里再聊起老生常谈的账户问题,通过个人银行账户问题,来逐渐引入 AtomicReferenc
- springboot对压缩请求的处理最近对接银联需求,为了节省带宽,需要对报文进行压缩处理。但是使用springboot自带的压缩设置不起作
- 背景最近在着手公司框架优化及项目实际应用,原先方案是springboot+html前后端分离单独部署,后端人员兼职前端开发,后续产品线业务进
- 我就废话不多说了,大家还是直接看代码吧~<resultMap id="ParentMap" type="
- 1、项目启动时报错如下Description:The bean 'securityManager', defined in
- 要说,这也是一个很简单的功能,没必要开一篇博客这么大动干戈。 对于一张知道全路径的照片,如果其路径包含后缀名的话,要取得后缀名,只需要一行代
- 作者: juky_huang 事件的简单解释: 事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如
- vs2010测试通过,主要思想是由出生日期和当前日期,两个日期计算出年龄(岁、月、天)using System;using System.C
- 初学spring,我在dao层初始化c3p0的时候,使用@Resource注解新建对象是发现注入为null,告诉我 java.la
- 一、整体设计1、需求分析池化技术是计算机中的一种设计模式,内存池是常见的池化技术之一,它能够有效的提高内存的申请和释放效率以及内存碎片等问题
- 实例如下所示:public class JsonExtracter { public static void main(String[] a
- 一、实战-内存溢出堆内存溢出栈内存溢出方法区溢出直接内存溢出二、实战-堆内存溢出演示堆内存溢出代码,并且定位问题总结堆内存溢出的场景与解决方
- 把最近听的写的一些题目做下笔记!1.下列程序的执行,说法错误的是 ( ABC )public class MultiCatch
- 一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的。关于委托的定义和使用,已经有诸多
- 本文实例为大家分享了C语言实现稀疏矩阵的具体代码,供大家参考,具体内容如下#include "stdio.h"#defi