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. 在.Net Core中使用Swagger制作接口文档

    在实际开发过程中后台开发人员与前端(移动端)接口的交流会很频繁.所以需要一个简单的接口文档让双方可以快速定位到问题所在. Swagger可以当接口调试工具也可以作为简单的接口文档使用. 在传统的asp ...

  2. mybatis中用注解如何处理存储过程返回的多个结果集?

    sql代码: create procedure sptest.getnamesanditems() reads sql data dynamic result sets 2 BEGIN ATOMIC ...

  3. 二.HTML

    1.HTML 1. <head></head>标签 <!DOCTYPE html> <!--统一规范--> <!----> <html ...

  4. idea中从代码自动定位到左侧类结构位置

    标题的意思表达的不是很清楚,下面是这个设置的方法: 图中红圈中就是设置的位置,把鼠标悬浮在上面,可以看到这个设置的名称是Autoscroll from source, 它的作用是,你在代码中点击一个方 ...

  5. 9.Javascript原生瀑布流

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&q ...

  6. psexec与wmi在内网渗透的使用

    psexec是一个很好的管理工具,在内网渗透中也被广泛使用. 但太“出名”也往往会遭来各种麻烦. 在有安全监听.防护的内网中使用psexec会容易触发告警. 1.psexec用法(前提:对方要开启ad ...

  7. iOS RACSubject代替通知

    RAC是一个很常用并且很好用的插件,简洁的调用方式可以代替很多原生方法,下面是RACSubject代替通知的使用方式: #import <UIKit/UIKit.h> #import &l ...

  8. linux系统IO操作

    本文重点说明下面内容: 什么是标准IO,什么是文件IO? 什么是Direct IO? O_SYNC标识有什么意义? 各个层面的缓存如何同步? 还在page cache中的脏页可以读写吗? IO路径上的 ...

  9. mysql数据库SQL执行分析,优化前必备分析

    概述 一般我们在对mysql数据库做优化,肯定需要对慢sql去做分析才能开始优化,那么有什么分析的方法呢?下面通过对sql执行时间和执行情况来做分析. 一.SQL 执行时间分析 通过找到执行时间长的 ...

  10. Httpd服务入门知识-Httpd服务常见配置案例之配置持久连接

    Httpd服务入门知识-Httpd服务常见配置案例之配置持久连接 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看默认的持久连接时间 [root@node101.yinzhe ...