光遇弹琴脚本怎么用_一招教你怎么用Java调用groovy脚本

最近手上有一个专项要做,专项思路大概就是开发一个服务将所有其他Java开发的自动化工具脚本收口,统一通过这个服务做调度转发。

5835dff7be38d49046146d549d10dac1.png

为什么要聊groovy呢?


大家也都知道,阿里、美团、滴滴、京东等大厂项目基本上都是Java栈为主,其实Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python和Ruby许多强大的特性,Groovy代码能够与Java代码很好地结合,也能用于扩展现有代码,学会Java调用groovy有利于更好的实现自动化。

Groovy有哪些特点呢?


  1. 为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。

  2. Groovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变得非常简单。

  3. groovy基本类型也是对象,可以直接调用对象的方法。

  4. 支持函数式编程,不需要main函数。

  5. 直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。

OK,接下来切入正题,介绍一下怎么通过Java调用Groovy脚本。

Java调用Groovy的几种方法


工具:IntelliJ IDEA

项目:maven项目

依赖:groovy-all包

    org.codehaus.groovy    groovy-all    3.0.7    pom

 一、GroovyShell执行groovy脚本 

  1. 通过evaluate方法执行groovy脚本

GroovyShell的evaluate方法非常类似于Js的eva方法,可执行一段字符串。

package com.robot.universalrobot.groovyTest;import groovy.lang.GroovyShell;import java.util.logging.Logger;import org.codehaus.groovy.control.CompilationFailedException;import java.io.IOException;/** * @Date 2021/1/1 7:33 下午 **/public class Test_002 {    public static void testGroovy2() throws CompilationFailedException, IOException {        GroovyShell groovyShell = new GroovyShell();        groovyShell.evaluate("println 'hello Groovy shell.'");    }    public static void main(String[] args) {        try {            testGroovy2();        } catch (IOException error){            error.getStackTrace();        }    }}

运行结果

9a9705ca0a277cd4bcdec9072883b7bc.png

  1. 通过evaluate方法调用groovy脚本文件

需要建一个groovy文件,定义要执行的脚本,例如定义一个无参的方法sayHello并调用该方法。

def sayHello() {    println 'Hello World.'}sayHello()

在Java中就可以直接调用这个groovy文件执行了,方法如下:

package com.robot.universalrobot.groovyTest;import groovy.lang.GroovyShell;import lombok.Data;import org.codehaus.groovy.control.CompilationFailedException;import java.io.File;import java.io.IOException;import java.util.logging.Logger;/** * @Date 2021/1/1 7:26 下午 **/@Datapublic class test_001 {    public static void testGroovy1() throws CompilationFailedException, IOException {        GroovyShell groovyShell = new GroovyShell();        Object result = groovyShell.evaluate(new File("src/main/java/com/robot/universalrobot/groovyTest/demo_001.groovy"));    }    public static void main(String[] args) {        try {            testGroovy1();        } catch (Exception error){            error.getStackTrace();        }    }}

执行结果

04eb573c5816b0434e82054ea2d96d5a.png

  1. 给groovy文件传参数并执行

package com.robot.universalrobot.groovyTestdef sayHello(name) {    println 'Hello World.' + name}sayHello(name)

Java调用groovy方法

public class test_001 {    public static void testGroovy1() throws CompilationFailedException, IOException {        // 调用带参数的groovy shell时,使用bind绑定数据        Binding binding = new Binding();        binding.setProperty("name", "软件质量保障");        GroovyShell groovyShell = new GroovyShell(binding);        Object result = groovyShell.evaluate(new File("src/main/java/com/robot/universalrobot/groovyTest/demo_001.groovy"));    }    public static void main(String[] args) {        try {            testGroovy1();        } catch (Exception error){            error.getStackTrace();        }    }}

执行结果

feb59a3322208eda28fca25665faad94.png

二、GroovyClassLoader动态加载Groovy Class

你也许熟悉Java的ClassLoader类加载器,当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM运行,负责加载Java class的这部分就叫做Class Loader。而GroovyClassLoader,顾名思义,就是用来加载Groovy类的加载器。

  1. 新建groovy class

class demo_002 {    String sayHello(String name, String sex, int age) {        return "name: " + name + ", sex: " + sex + ", age: " + age;    }}
  1. 编写Java调用文件

import groovy.lang.GroovyClassLoader;import groovy.lang.GroovyObject;import org.codehaus.groovy.control.CompilerConfiguration;import java.io.File;/** * @Date 2021/1/1 7:58 下午 **/public class Test_003 {    private static GroovyClassLoader groovyClassLoader = null;    public static void initGroovyClassLoader() {        CompilerConfiguration config = new CompilerConfiguration();        config.setSourceEncoding("UTF-8");        // 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)        groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);    }    /**     * 通过GroovyClassLoader加载GroovyShell_2,并反射调用其sayHello(String name, String sex, int age)方法     *     */    public static String invokeSayHello(String name, String sex, int age) {        String result = "";        File groovyFile = new File("src/main/java/com/robot/universalrobot/groovyTest/demo_002.groovy");        if (!groovyFile.exists()) {            return result;        }        try {            // 获得GroovyShell_2加载后的class            Class> groovyClass = groovyClassLoader.parseClass(groovyFile);            // 获得GroovyShell_2的实例            GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();            // 反射调用sayHello方法得到返回值            Object methodResult = groovyObject.invokeMethod("sayHello", new Object[] {name, sex, age});            if (methodResult != null) {                result = methodResult.toString();            }        } catch (Exception e) {            e.getStackTrace();        }        return result;    }    public static void main(String[] args) throws Exception {        initGroovyClassLoader();        System.out.println(invokeSayHello("张三", "男", 25));    }}

执行结果

7a6ede999457615ad3093b09eea94df3.png

其方式和Java中类的加载反射类似,需要注意的是GroovyClassLoader与Java中的加载器一样,同一个类名的类只能加载一次,如果想再次加载,必须调用GroovyClassLoader的clearCache()方法移除所有已经加载的Groovy Class。

三、GroovyScriptEngine脚本引擎加载Groovy脚本

GroovyScriptEngine从指定的位置(文件系统,URL,数据库等等)加载Groovy脚本,并且随着脚本变化可重新加载它们。GroovyScriptEngine也可以传进变量值返回脚本的计算结果。

以上面栗子中的groovy文件为例。

编写使用GroovyScriptEngine从com.juxinli.groovy.shell包中加载、运行这些script

package com.robot.universalrobot.groovyTest;import groovy.util.GroovyScriptEngine;import groovy.lang.Binding;/** * @Date 2021/1/1 8:07 下午 **/public class test_004 {    public static void main(String[] args) throws Exception {        // GroovyScriptEngine的根路径,如果参数是字符串数组,说明有多个根路径        GroovyScriptEngine engine = new GroovyScriptEngine("src/main/java/com/robot/universalrobot/groovyTest");        Binding binding = new Binding();        binding.setVariable("name", "软件质量保障");        Object result1 = engine.run("demo_001.groovy", binding);        Object result2 = engine.run("demo_003.groovy", binding);    }}

执行结果86a0471f42fbb09b23973a03f494c947.png

好啦,以上就是总结的几种执行groovy脚本的方法,欢迎转载分享。

参考文档

https://tool.oschina.net/apidocs/apidoc?api=groovy


版权声明:本文为weixin_28744423原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。