Java动态调用脚本语言Groovy

2019-05-15

目录

0. pom.xml添加依赖
1. 使用GroovyShell计算表达式
2. 使用GroovyScriptEngine脚本引擎加载Groovy脚本
3. 使用GroovyClassLoader动态地载入Groovy的类
4. 使用JAVA脚本API

0. pom.xml添加依赖

  1. <dependency>
  2. <groupId>org.codehaus.groovy</groupId>
  3. <artifactId>groovy-all</artifactId>
  4. <version>2.5.6</version>
  5. <type>pom</type>
  6. </dependency>

1.使用GroovyShell计算表达式

使用Binding对象将变量传入表达式,并通过GroovyShell返回表达式的计算结果。

GroovyShellExample.java

  1. import groovy.lang.Binding;
  2. import groovy.lang.GroovyShell;
  3.  
  4. public class GroovyShellExample {
  5. public static void main(String args[]) {
  6. Binding binding = new Binding();
  7. binding.setVariable("x", 10);
  8. binding.setVariable("language", "Groovy");
  9.  
  10. GroovyShell shell = new GroovyShell(binding);
  11. Object value = shell.evaluate("println \"Welcome to $language\"; y = x * 2; z = x * 3; return x ");
  12.  
  13. System.err.println(value +", " + value.equals(10));
  14. System.err.println(binding.getVariable("y") +", " + binding.getVariable("y").equals(20));
  15. System.err.println(binding.getVariable("z") +", " + binding.getVariable("z").equals(30));
  16. }
  17. }

运行结果如下:

  1. Welcome to Groovy
  2. 10, true
  3. 20, true
  4. 30, true

2.使用GroovyScriptEngine脚本引擎加载Groovy脚本

GroovyScriptEngine从指定的位置(文件系统,URL,数据库等等)加载Groovy脚本,并且随着脚本变化可重新加载它们。和GroovyShell一样,GroovyScriptEngine也可以传进变量值返回脚本的计算结果。这样我们可以把一些可用的计算公式或计算条件写入Groovy脚本中来执行应用计算。当这些公式或计算条件变更时,我们可更方便地进行更改计算。

GroovyScriptEngineExample.java

  1. import groovy.lang.Binding;
  2. import groovy.util.GroovyScriptEngine;
  3.  
  4. public class GroovyScriptEngineExample {
  5. public static void main(String args[]) {
  6. try {
  7. String[] roots = new String[]{".\\src\\sample\\"} ;//定义Groovy脚本引擎的根路径
  8. GroovyScriptEngine engine = new GroovyScriptEngine(roots);
  9. Binding binding = new Binding();
  10. binding.setVariable("language", "Groovy");
  11. Object value = engine.run("SimpleScript.groovy", binding);
  12. assert value.equals("The End");
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }
  1. SimpleScript.groovy
  1. println "Welcome to $language"
  2. return "The End"

运行结果如下:

  1. Welcome to Groovy

3.使用GroovyClassLoader动态地载入Groovy的类

下例现示如何使用GroovyClassLoader加载Groovy类并且调用该类的一个方法。

GroovyClassLoaderExample.java

  1. import groovy.lang.GroovyClassLoader;
  2. import groovy.lang.GroovyObject;
  3. import java.io.File;
  4.  
  5. public class GroovyClassLoaderExample {
  6. public static void main(String args[]) {
  7. try {
  8. GroovyClassLoader loader = new GroovyClassLoader();
  9. Class fileCreator = loader.parseClass(new File("src\\sample\\GroovySimpleFileCreator.groovy"));
  10. GroovyObject object = (GroovyObject) fileCreator.newInstance();
  11. object.invokeMethod("createFile", "D:\\temp\\emptyFile.txt");
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }

GroovySimpleFileCreator.groovy

  1. class GroovySimpleFileCreator {
  2. public createFile(String fileName){
  3. File file = new File(fileName);
  4. file.createNewFile();
  5. }
  6. }

使用GroovyClassLoader另一种情景便是:存在一个Java接口和一个实现该Java接口的Groovy类。此时,可以通过GroovyClassLoader加载Groovy实现类到应用中,这样就可以直接调用该接口的方法。

IFoo.java

  1. public interface IFoo {
  2. Object run(Object foo);
  3. }

InvokeGroovy.java

  1. import groovy.lang.GroovyClassLoader;
  2.  
  3. public class InvokeGroovy {
  4. public static void main(String[] args) {
  5. ClassLoader cl = new InvokeGroovy().getClass().getClassLoader();
  6. GroovyClassLoader groovyCl = new GroovyClassLoader(cl);
  7. try {
  8. //从文件中读取,将实现IFoo接口的groovy类写在一个groovy文件中
  9. //Class groovyClass = groovyCl.parseClass(new File("./src/sample/Foo.groovy"));
  10. //直接使用Groovy字符串,也可以获得正确结果
  11. Class groovyClass = groovyCl.parseClass("class Foo implements IFoo {public Object run(Object foo) {return 2+2>1}}");//这个返回true
  12. IFoo foo = (IFoo) groovyClass.newInstance();
  13. System.out.println(foo.run(new Integer(2)));
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. }
  18. }

运行结果如下:

  1. true

4.使用JAVA脚本API

Java SE 6 引入了对 Java Specification Request(JSR)223 的支持,JSR 223 旨在定义一个统一的规范,使得 Java 应用程序可以通过一套固定的接口与各种脚本引擎交互,从而达到在 Java 平台上调用各种脚本语言的目的。每一个脚本引擎就是一个脚本解释器,负责运行脚本,获取运行结果。ScriptEngine 接口提供了许多 eval 函数的变体用来运行脚本,这个函数的功能就是获取脚本输入,运行脚本,最后返回输出。

GroovyJSR223Example.java

  1. import javax.script.Invocable;
  2. import javax.script.ScriptEngine;
  3. import javax.script.ScriptEngineManager;
  4.  
  5. public class GroovyJSR223Example {
  6. public static void main(String args[]) {
  7. try {
  8. ScriptEngineManager factory = new ScriptEngineManager();
  9. ScriptEngine engine = factory.getEngineByName("groovy");
  10. String HelloLanguage = "def hello(language) {return \"Hello $language\"}";
  11. engine.eval(HelloLanguage);
  12. Invocable inv = (Invocable) engine;
  13. Object[] params = {new String("Groovy")};
  14. Object result = inv.invokeFunction("hello", params);
  15. //assert result.equals("Hello Groovy");
  16. System.out.println(result);
  17. } catch (Exception e) {
  18. // TODO Auto-generated catch block
  19. e.printStackTrace();
  20. }
  21. }
  22. }

运行结果如下:

  1. Hello Groovy

参考:

[1] Java中运行动态脚本Groovy

[2] Java动态调用脚本语言Groovy,完善接口配置

[3] Java结合Groovy让程序支持动态算法打赏

[4] 基于Groovy的规则脚本引擎实战

Java动态调用脚本语言Groovy的更多相关文章

  1. Java动态调用webService,axis2动态调用webService

    Java动态调用webService axis2动态调用webService >>>>>>>>>>>>>>>& ...

  2. Java学习笔记--脚本语言支持API

    Java语言的动态性之脚本语言支持API 随着Java平台的流行,很多的脚本语言(scripting language)都可以运行在Java虚拟机啊上,其中比较流行的有JavaScript.JRuby ...

  3. [Java面试九]脚本语言知识总结.

    核心内容概述 1.JavaScript加强,涉及到ECMAScript语法.BOM对象.DOM对象以及事件. 2.Ajax传统编程. 3.jQuery框架,九种选择器为核心学习内容 4.JQuery ...

  4. Java JNI调用c语言的dll测试

    最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...

  5. 适用于Java的嵌入式脚本语言

    此文已由作者赵昕授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. fakescript 轻量级嵌入式脚本语言 https://github.com/esrrhs/fakescr ...

  6. Java语言与C语言混合编程(2)--在Java中调用C语言本地库

    在上一篇文章中介绍了Java语言中的native关键字,以及Java语言调用C语言的编译生成本地动态链接库(DLL)实现加法运算的小例子,本文通过一个更加详细的例子,深入讲解Java语言调用C语言的函 ...

  7. java jni 调用c语言函数

    今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...

  8. Java如何调用C语言程序,JNI技术

    Java为什么要调用C语言编写的程序因为涉及操作系统底层的事件,Java是处理不了的,例如用户上传一个视频文件,需要后台给视频加上水印,或者后台分离视频流和音频流,这个事Java就做不了,只能交给C语 ...

  9. C#调用脚本语言(三)-- IronJS 与 IronLua 简单方法性能比较

    1.   测试环境 1.1. 硬件环境 CPU:intel Core i7-740QM 内存:8GDDR3 Memory 1.2. 系统 系统:Windows 8 Enterprise 开发工具:Vs ...

随机推荐

  1. Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag

    Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静 ...

  2. 2019-07-29 ThinkPHP简单的增删改查

    在model里面,建立表名Model.class.php的控制器,用以连接数据表,代码如下 namespace Home\Model; use Think\Model; class NewsModel ...

  3. 阿里sentinel源码研究深入

    1. 阿里sentinel源码研究深入 1.1. 前言 昨天已经把sentinel成功部署到线上环境,可参考我上篇博文,该走的坑也都走了一遍,已经可以初步使用它的限流和降级功能,根据我目前的实践,限流 ...

  4. echarts自定义悬浮框的显示

    最近在使用echarts的地图功能 ,业务需求是显示前五的具体信息,并且轮流显示,首先解决轮流显示的问题 var counta = 0; //播放所在下标 var mTime = setInterva ...

  5. js学习之数据结构和算法

    js中的数据结构 1.列表 待办事项列表.购物清单.最佳十名榜单等等. 适用: 1)数据结构较为简单, 2)不需要在一个长序列中查找元素,或者对其进行排序 2.栈 一摞盘子 ----- 添加删除只能从 ...

  6. 自动化测试模型 Selenium IDE Selenium Gird2

    1.线性测试 每个测试脚本相对独立,且不产生其他依赖与调用,其实就是单纯的来模拟用户完整的 操作场景.前一篇所写的测试脚本就属于线性测试. 优点:每个脚本完整且独立 缺点:测试用例的开发与维护成本高 ...

  7. [ ERROR ] Error in test library 'pymysql': Creating keyword 'Connect' failed: Keyword with same name defined multiple times.

    [ ERROR ] Error in test library 'pymysql': Creating keyword 'Connect' failed: Keyword with same name ...

  8. 一、MySQL基础知识

    一.背景介绍 我们每天都在访问各种网站.APP,如微信.QQ.抖音,今日头条等,这些东西上面都存在大量的信息,这些信息都需要有地方存储,存储在哪里呢?数据库. 所有我们需要开发一个网站.APP,数据库 ...

  9. .Net Core 2.2 发布IIS遇到的那些坑

    这两天在研究.Net Core 发布iis总结一下. 我主要是参照官方文档: https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/ ...

  10. pyechart基本使用大全

    charts_base 原文链接:https://blog.csdn.net/weixin_43735353/article/details/89328048 图表详细配置请参考 图表配置篇 基本图表 ...