详解Java执行groovy脚本的两种方式

作者:蒲公英不是梦 时间:2021-05-28 09:23:27 

记录Java执行groovy脚本的两种方式,简单粗暴:

一种是通过脚本引擎ScriptEngine提供的eval(String)方法执行脚本内容;一种是执行groovy脚本;

二者都通过Invocable来传递参数并获取执行结果;

Invocable:脚本引擎的解释器接口,提供invokeFunctioninvokeMethod两种传递参数并获取执行结果的方法,Java JDK API文档解释如下:

详解Java执行groovy脚本的两种方式

invokeFunction:

详解Java执行groovy脚本的两种方式

invokeMethod:

详解Java执行groovy脚本的两种方式

以下为案例:

引入依赖


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

运行结果:

详解Java执行groovy脚本的两种方式

  • invokeFunction方法的第一个参数为脚本的函数名称,把scriptName拎出来通过创建String对象再赋值进去,方便你看懂函数名称到底是哪个;

  • scriptContent${date.getTime()}$name的意思一样,grovvy中的字符串可以识别${}$占位符;

  • bindings绑定参数与invokeFunction方法的第二个参数的区别是,前者是脚本内全局的,而后者是定义在函数内的;

例如把脚本内容定义为这样:

详解Java执行groovy脚本的两种方式

执行结果就是这样了:

详解Java执行groovy脚本的两种方式

实例化脚本对象并执行


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

运行结果:

详解Java执行groovy脚本的两种方式

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

标签:Java,groovy,脚本
0
投稿

猜你喜欢

  • android如何获取view在布局中的高度与宽度详解

    2023-08-14 17:17:51
  • Android实时文件夹创建方法

    2023-11-30 03:13:42
  • Android仿Keep运动休息倒计时圆形控件

    2022-08-02 07:54:36
  • Java 微信公众号开发相关总结

    2021-11-11 03:43:30
  • Android 完全退出的实例详解

    2022-11-01 22:56:22
  • c#中task与thread区别及其使用的方法示例

    2021-08-06 13:59:10
  • JVM完全解读之GC日志记录分析

    2022-09-22 12:43:08
  • C#使用Socket实现本地多人聊天室

    2022-01-06 12:47:27
  • Spring自动注入失败的解决方法

    2022-08-13 03:41:31
  • 解决spring mvc 多数据源切换,不支持事务控制的问题

    2022-09-30 03:39:56
  • C#操作注册表的方法

    2023-06-24 14:34:46
  • Android Studio工程导入及坑的解决

    2022-01-12 20:48:31
  • 一文带你入门SpringMVC的配置与使用

    2021-06-24 12:30:52
  • C# params可变参数的使用注意详析

    2021-10-29 12:33:27
  • Hadoop源码分析六启动文件namenode原理详解

    2021-08-20 01:03:55
  • Java实现五子棋游戏

    2022-07-08 12:50:27
  • 使用XSD校验Mybatis的SqlMapper配置文件的方法(2)

    2023-06-29 07:51:34
  • Spring4下validation数据校验无效(maven)的解决

    2022-01-24 03:01:04
  • 读写Android中assets目录下的文件的方法详解

    2023-03-03 15:50:35
  • Spring Boot Thymeleaf实现国际化的方法详解

    2023-11-24 06:01:01
  • asp之家 软件编程 m.aspxhome.com