Springboot项目中加载Groovy脚本并调用其内部方代码实现

这篇具有很好参考价值的文章主要介绍了Springboot项目中加载Groovy脚本并调用其内部方代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

项目中部署到多个煤矿的上,每一种煤矿的情况都相同,涉及到支架的算法得写好几套,于是想到用脚本实现差异变化多的算法!一开始想到用java调用js脚本去实现,因为这个不需要引入格外的包,js对我来说也没啥学习成本,后来发现js的方法的参数中没办法使用java的对象传参。如果要把java对象分解成多个基本类型的参数传递的话,js的代码实现就变复杂和臃肿了。于是改用groovy脚本去实现,后来经过两个小时的实现,终于调通!groovy的语法和java类似,学习成本很低,且groovy可以引入java的类使用java的对象,调用java的方法也很简单,下面给出实现的代码图文教程。

Groovy简介

Groovy是一种基于JVM(Java虚拟机)的动态编程语言,它具有Java的兼容性和许多强大的功能,可以用来快速开发Java应用程序。

以下是Groovy的一些主要特点:

  • 静态类型:Groovy是静态类型的语言,这意味着你可以在编译时检测到许多常见的错误,从而提高代码的质量和可维护性。
  • 动态类型:同时,Groovy也是动态类型的语言,这意味着你可以在运行时动态地改变变量的类型,这使得Groovy代码更加灵活和易读。
  • 强大的语法:Groovy的语法比Java更简洁、更易读。它支持多种编程范式,如面向对象编程和函数式编程。
  • 与Java无缝集成:Groovy可以与Java代码无缝集成,这意味着你可以在Groovy代码中使用Java类库,反之亦然。这使得Groovy成为Java开发者的强大工具。
  • 简洁的语法:与Java相比,Groovy的语法更为简洁。它支持许多Java不支持的特性,如可选的括号、可选的类型声明等。
  • 强大的元编程能力:Groovy具有强大的元编程能力,它允许你在运行时动态地修改代码。这使得Groovy成为快速开发原型或快速实现想法的有力工具。
  • 测试驱动开发:Groovy支持测试驱动开发(TDD),它使得你可以快速编写测试代码并以此驱动你的业务逻辑代码。
  • 闭包:Groovy支持闭包,这是一种可以包含代码块的语法结构,可以作为参数传递给函数,也可以赋值给变量。
  • 运行时类型检查:虽然Groovy是动态类型的语言,但它也支持运行时类型检查,这使得你可以在运行时捕获许多类型错误。
  • AST变换:Groovy允许你直接操作Java字节码,这使得你可以在编译时对代码进行修改。这是许多静态类型语言无法提供的功能。

总的来说,Groovy是一种强大、灵活且易于使用的编程语言,无论你是一个Java开发者还是一个想要使用JVM的语言的人,你都可以从Groovy中受益。

教程

引入依赖

首先在springboot项目中引入groovy的依赖,maven引入配置如下:

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.11</version>
        </dependency>

java加载使用脚本工具类

新建一个ScriptProvider脚本使用类,代码如下:


import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author Lenovo
 */
@Component
@Slf4j
public class ScriptProvider {

    private GroovyObject groovyObject;

    @Value("${app.work-face}")
    private  void loadScript(String name){
        try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
            Class<?> groovyClass = classLoader.parseClass(new File("etc/"+name+".groovy"));
            groovyObject= (GroovyObject) groovyClass.newInstance();
        } catch (InstantiationException | IOException | IllegalAccessException e) {
            log.error(e.getMessage());
        }
    }

    public  void overloadScript(String filePath){
        try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
            Class<?> groovyClass = classLoader.parseClass(new File(filePath));
            groovyObject= (GroovyObject) groovyClass.newInstance();
        } catch (InstantiationException | IOException | IllegalAccessException e) {
            log.error(e.getMessage());
        }
    }

    public double calStentHeight(int i, List<DataValue> dataValues){
        Object[] objects = new Object[]{i,dataValues};
        Object result=groovyObject.invokeMethod("calStentHeight",objects);
        return Double.parseDouble(result.toString());
    }

    public double revisedStentHeight(int i, List<DataValue> dataValues){
        Object[] objects = new Object[]{i,dataValues};
        Object result=groovyObject.invokeMethod("revisedStentHeight",objects);
        return Double.parseDouble(result.toString());
    }

    public Object revisedStentStroke(int i, List<DataValue> dataValues) {
        Object[] objects = new Object[]{i,dataValues};
        Object result=groovyObject.invokeMethod("revisedStentStroke",objects);
        return Double.parseDouble(result.toString());
    }
}

代码解析

  • 在spring配置文件中配置不同的脚本名,通过@Value(“${app.work-face}”) 注解 ,在项目启动时加载对应的groovy脚本文件。
  • invokeMethod(“calStentHeight”,objects); calStentHeight 是groovy脚本中定义的方法,objects数组是groovy脚本中方法的参数,objects数组数组的元素顺序和方法的参数保持一致。
  • new File(“etc/”+name+“.groovy”) 是读入项目根目录下,etc文件夹下的某个groovy脚本文件,打成jar运行的时候,读取的是jar同级目录下,etc文件夹下的某个groovy脚本文件。

Springboot项目中加载Groovy脚本并调用其内部方代码实现,粉丝专栏,spring boot,后端,groovy,java

groovy脚本

创建一个groovy脚本,以4703.groovy为例,代码如下:

import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue


def calStentHeight(int i,List<DataValue> dataValues){
    return dataValues.get(i).getValue().getValue();
}

def revisedStentHeight(int i,List<DataValue> dataValues){
    double d=dataValues.get(i).getValue().getValue();
    int stentNo=i+1;
    if(stentNo<=2||stentNo>=92){
        if(d>3.6){
            d=3.6;
        }
        if(d<=0){
            d=3.3;
        }
    }else{
        if(d>1.9){
            d=stentNo==3?1.9:dataValues.get(i-1).getValue().getValue();
        }
        if(d<=0){
            d=1.9;
        }
    }
    return d;
}

def revisedStentStroke(int i,List<DataValue> dataValues){
    double d=dataValues.get(i).getValue().getValue();
    int stentNo=i+1;
    if(stentNo<=2||stentNo>=92){
        if(d>900D){
            d=900D;
        }
        if(d<=0D){
            d=0D;
        }
    }else{
        if(d>900D||d<=0D){
            d=dataValues.get(i-1).getValue().getValue();;
        }
    }
    return d;
}

代码解析:

  • DataValue对象是java opc开源工具获取,opc点位对应值返回的对象。
  • groovy的方法内部可以向java一样编写

java调用groovy脚本的方法

在springboot中调用groovy脚本中的方法,示例代码如下:

    @Resource
    private ScriptProvider scriptProvider;

    StentsDTO.putStentHeight(key.getPointAddress(),scriptProvider.calStentHeight(i,dataValues));
    objValue= scriptProvider.revisedStentHeight(i,dataValues);

代码解析

  • 通过@Resource注解将ScriptProvider类注入到spring的容器中,通过ScriptProvider的实例对象,调用内部方法。

groovy脚本修改监听类实现

java无法是实现对具体某个文件操作事件的监听,只能实现文件夹和文件夹下的文件的事件的监听。我们可以通过监听文件夹监听实现对文件的监听。代码如下(代码中只有文件修改事件的监听):


import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.*;

/**
 * @author tarzan
 */
@Component
@AllArgsConstructor
@Slf4j
public class FileSystemWatcher {

    private final ScriptProvider scriptProvider;

    public void modifyWatch(){
        try {
            watch(StandardWatchEventKinds.ENTRY_MODIFY);
        } catch (IOException | InterruptedException e) {
            log.error(e.getMessage());
        }
    }

    private  void watch(WatchEvent.Kind<Path> eventKind) throws IOException, InterruptedException {
        // 定义你想要监听的路径
        Path path = Paths.get("etc");
        // 创建 WatchService
        WatchService watchService = FileSystems.getDefault().newWatchService();
        // 将路径注册到 WatchService,并指定你想要监听的事件类型
        path.register(watchService, eventKind);

        while (true) {
            // 获取下一个文件系统事件
            WatchKey key = watchService.take();
            for (WatchEvent<?> event : key.pollEvents()) {
                // 获取事件类型
                WatchEvent.Kind<?> kind = event.kind();
                if (kind == StandardWatchEventKinds.OVERFLOW) {
                    continue;
                }
                // 获取发生事件的文件
                WatchEvent<Path> ev = (WatchEvent<Path>) event;
                Path fileName = ev.context();
                // 打印出发生事件的文件名和事件类型
                boolean eventFlag=!fileName.toFile().getName().endsWith("~");
                if(eventFlag){
                    log.info("etc/"+fileName +" be modified");
                    scriptProvider.overloadScript("etc/"+fileName);
                }
            }
            //睡眠1秒
            Thread.sleep(1000);
            // 重置 WatchKey,以便接收下一个事件
            boolean valid = key.reset();
            if (!valid) {
                break;
            }
        }

    }

}

代码解析

  • 代码通过监听etc文件,当监听到etc文件夹下的文件进行修改操作或者覆盖操作的事件,就会重新加载修改后的grooy脚本文件。

结语

如果你对文章有疑问或者更好的见解,请在评论区留言!如果文章对你有帮助,请点赞收藏!!!文章来源地址https://www.toymoban.com/news/detail-724879.html

到了这里,关于Springboot项目中加载Groovy脚本并调用其内部方代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Groovy系列三 Java SpringBoot 整合 Groovy

      目录 一、概述 一、在Java中使用Groovy: 二、在Groovy中使用Java: 三、几种范式的不同、优缺点 Java调用Groovy的类和方法: Groovy调用Java的类和方法:  使用GroovyShell执行Groovy脚本: 使用GroovyClassLoader加载和执行Groovy脚本: 二、实战 第一步、与SpringBoot集成,引入依赖 第二步、

    2024年02月08日
    浏览(32)
  • SpringBoot整合Groovy示例

    1.添加Groovy依赖 2.创建Groovy脚本 创建一个Groovy脚本文件,例如 script.groovy 。在此文件中编写您的Groovy代码。 3.创建Spring Boot Controller 创建一个Spring Boot Controller,例如 GroovyController 。在此控制器中,您可以使用 GroovyScriptEngine 来执行您的Groovy脚本。 在上面的示例中,我们创建了

    2024年02月07日
    浏览(24)
  • uniapp JS文件里面调用自定义组件(不用每个页面在template中加组件标签)

    前言 工具:uniapp ( Vue2 ) 开发端:微信小程序 其他:uview 2.0 场景:路由器里面,统一验证是否已登录,如果没登录,则直接弹出登录弹窗出来,不管哪个页面都可以直接弹出此组件不需每个页面去加入组件标签。 效果如下: 直接上代码: 第一步:组件封装 components目录下

    2024年02月16日
    浏览(36)
  • SpringBoot项目(jar)部署,启动脚本

    SpringBoot项目(jar)部署,需要先关闭原来启动的项目,再启动新的项目。直接输入命令,费时费力,还容易出错。所以,使用脚本启动。 脚本名: start.sh 此脚本需要放置在jar包的同级目录,才能正确找到jar包。 在脚本所在目录,执行如下命令: 一开始,我在给pid赋值时,

    2024年02月10日
    浏览(33)
  • IDEAJava项目使用Groovy文件编译的时候报错的解决, 以及Groovy的使用

    Cannot compile Groovy files: no Groovy library is defined for module 模块需要引入插件和依赖 . 如下 ${project.basedir} 是pom中的常量 , 项目的路径 /src/main/java/cn/com/baidu/message/groovy  是我的groovy文件所在的包路径 Maven的Plugins中会出现gplus的插件 , 点击compile先编译groovy文件 , 编译后在target查看是否

    2024年02月13日
    浏览(40)
  • SpringBoot 项目中 对http调用异常处理

    spring 中 http调用 resp 会返回3个值 status/heard/body 分2种情况的异常 1.status 代表了通信异常, 也是我们常说的 http 状态码         只能是纯数字         200-成功, 404-不能访问的资源, 500-服务器异常         比较坑的是, 有些服务会, 把业务异常和这个进行合并, 或者篡改  2.bod

    2024年02月17日
    浏览(28)
  • 在Springboot项目中使用Redis提供给Lua的脚本

    在Spring Boot项目中,你可以使用RedisTemplate来执行Lua脚本。RedisTemplate是Spring Data Redis提供的一个Redis客户端,它可以方便地与Redis进行交互。以下是使用RedisTemplate执行Lua脚本的一般步骤: 添加Spring Data Redis依赖: 首先,确保你的Spring Boot项目中已经添加了Spring Data Redis依赖。你可

    2024年02月07日
    浏览(26)
  • Solon2 之 Groovy 语言开发后端接口项目

    今天再做个新的尝试,用 Solon 框架写个 Groovy 后端项目。借助 “Solon Initializr” 生成个项目模板,会比较方便。 打开“Solon Initializr” :https://solon.noear.org/start/ ,在语言那儿选择\\\" Groovy\\\",再选上项目类型为“Gradle - Groovy”。然后点“生成”就会自动下载\\\"demo.zip\\\"文件了。 解压

    2023年04月08日
    浏览(26)
  • 解决Docker部署SpringBoot项目时各容器的相互调用

    目录 一、项目问题场景: 二、问题分析: 三、解决各容器互相调用的办法: 1、第一步: 2、第二步: 3、第三步: 一、项目问题场景: 项目打包成jar包后,通过 可以正常连接我本地的docker容器中的其他服务,如mysql,nacos,sentinel,rabbitmq等等 但是当我将这个jar包打包成镜

    2024年02月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包