zoukankan      html  css  js  c++  java
  • Java动态调用脚本语言Groovy

    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的规则脚本引擎实战

  • 相关阅读:
    mvc5+ef6+Bootstrap 项目心得--创立之初
    C# StopWatch的使用
    MVC Form异步请求
    bootstrap-datepicker带中文的js文件
    bootstrap
    mvc5+ef6+Bootstrap 项目心得--WebGrid
    mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理
    关于mvc5+EF里面的db.Entry(model).State = EntityState.Modified报错问题
    将DBF文件导入Sqlserver数据库
    MySQL主从报错解决:Failed to initialize the master info structure
  • 原文地址:https://www.cnblogs.com/Ming8006/p/10870696.html
Copyright © 2011-2022 走看看