Java动态调用脚本语言Groovy

2019-05-15

目录

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

0. pom.xml添加依赖

        <dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.5.6</version>
<type>pom</type>
</dependency>

1.使用GroovyShell计算表达式

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

GroovyShellExample.java

import groovy.lang.Binding;
import groovy.lang.GroovyShell; public class GroovyShellExample {
public static void main(String args[]) {
Binding binding = new Binding();
binding.setVariable("x", 10);
binding.setVariable("language", "Groovy"); GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("println \"Welcome to $language\"; y = x * 2; z = x * 3; return x "); System.err.println(value +", " + value.equals(10));
System.err.println(binding.getVariable("y") +", " + binding.getVariable("y").equals(20));
System.err.println(binding.getVariable("z") +", " + binding.getVariable("z").equals(30));
}
}

运行结果如下:

Welcome to Groovy
10, true
20, true
30, true

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

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

GroovyScriptEngineExample.java

import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine; public class GroovyScriptEngineExample {
public static void main(String args[]) {
try {
String[] roots = new String[]{".\\src\\sample\\"} ;//定义Groovy脚本引擎的根路径
GroovyScriptEngine engine = new GroovyScriptEngine(roots);
Binding binding = new Binding();
binding.setVariable("language", "Groovy");
Object value = engine.run("SimpleScript.groovy", binding);
assert value.equals("The End");
} catch (Exception e) {
e.printStackTrace();
}
}
}
SimpleScript.groovy
println "Welcome to $language"
return "The End"

运行结果如下:

Welcome to Groovy

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

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

GroovyClassLoaderExample.java

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File; public class GroovyClassLoaderExample {
public static void main(String args[]) {
try {
GroovyClassLoader loader = new GroovyClassLoader();
Class fileCreator = loader.parseClass(new File("src\\sample\\GroovySimpleFileCreator.groovy"));
GroovyObject object = (GroovyObject) fileCreator.newInstance();
object.invokeMethod("createFile", "D:\\temp\\emptyFile.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
}

GroovySimpleFileCreator.groovy

class GroovySimpleFileCreator {
public createFile(String fileName){
File file = new File(fileName);
file.createNewFile();
}
}

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

IFoo.java

public interface IFoo {
Object run(Object foo);
}

InvokeGroovy.java

import groovy.lang.GroovyClassLoader;

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

运行结果如下:

true

4.使用JAVA脚本API

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

GroovyJSR223Example.java

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager; public class GroovyJSR223Example {
public static void main(String args[]) {
try {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
String HelloLanguage = "def hello(language) {return \"Hello $language\"}";
engine.eval(HelloLanguage);
Invocable inv = (Invocable) engine;
Object[] params = {new String("Groovy")};
Object result = inv.invokeFunction("hello", params);
//assert result.equals("Hello Groovy");
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

运行结果如下:

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. 简约而不简单的Django2.2 新手图文教程

     欢迎大家访问我的个人网站<刘江的博客和教程>www.liujiangblog.com  主要分享Python 及Django教程以及相关的博客! 版权所有,转载需注明来源! 2019年7 ...

  2. Jmeter的安装与配置。

    1.本机配置好JAVA环境. 2.官网下载压缩包,在任意目录下解压. 3.修改配置文件 ,打开Jmeter的bin目录下jmeter.porperties,修改 language=zh_CN samp ...

  3. Beego 学习笔记11:文件的上传下载

    文件的上传和下载 1->文件的上传 文件的上传,采用的是uploadify.js这个插件. 本事例实现的是上传图片文件,其他的文件上传也一样. 2->文件的下载 文件的下载有两个实现的方式 ...

  4. Python 栈、队列的实现

    在python中,列表既可以作为栈使用,又可以作为队列使用. 把列表作为栈使用 栈:后进先出 stack=[1,2,3] stack.append(4) #入栈,以列表尾部为栈顶 print(stac ...

  5. 数据分组统计函数族——apply族用法与心得

    笔者寄语:apply族功能强大,实用,可以代替很多循环语句,R语言中不要轻易使用循环语句. 原文链接: https://blog.csdn.net/sinat_26917383/article/det ...

  6. linux cgroups简介(下)Cgroups 与 Systemd

    Cgroups 是 linux 内核提供的一种机制,如果你还不了解 cgroups,请参考前文<Linux cgroups 简介>先了解 cgroups.当 Linux 的 init 系统 ...

  7. Httpd服务入门知识-Httpd服务常见配置案例之虚拟主机

    Httpd服务入门知识-Httpd服务常见配置案例之虚拟主机 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.虚拟主机实现方案 1>.Apache httpd 有三种实现虚 ...

  8. Appium中wait_activity的使用以及XPATH定位

    # -*- coding:utf-8 -*- from appium import webdriver from time import sleep desired_caps ={ 'platform ...

  9. nuxt build 项目文件分析、nuxt build 发布后的资源如何部署cdn

    建议在项目发布的时候,还是将.nuxt 进行发布到生产环境,是比较稳妥的做法 出处:https://nickfu.com/p/150 nuxt build 后的前端资源都会存放在.nuxt/dist/ ...

  10. Ofbiz项目学习——阶段性小结——更新数据

    一.根据一个字段进行修改 /** * 根据一个字段进行修改(这个条件字段可以是主键, 也可以不是主键) * @param dctx * @param context * @return */ publ ...