Springboot 集成 Groovy Script 完整示例

2023-11-05

Springboot 集成 Groovy Script 完整示例

使用Spring Boot集成Groovy Script来实现动态规则解析和执行的Demo,以下是实现步骤:

1. 创建Spring Boot项目:

首先,创建一个Spring Boot项目并添加所需的依赖项。可以使用Spring Initializr()链接: https://start.spring.io/进行项目初始化,并添加以下依赖项:

  • Spring Web:用于创建RESTful API
  • Spring Data Redis:用于与Redis进行交互

2. 编写Groovy脚本:

在项目中创建Groovy脚本文件,例如 RuleScript.groovy,用于定义动态规则的逻辑。脚本文件可以包含多个方法或者直接在脚本中编写执行逻辑。

示例脚本内容:

class RuleScript {
    def execute() {
        // 动态规则的执行逻辑
        println("执行动态规则")
    }
}

3. 配置Redis连接:

application.properties(或application.yml)文件中配置Redis连接信息,包括Redis主机、端口和密码等。这些配置将在后续步骤中使用。

示例配置:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=your_password

请根据实际情况替换为正确的Redis连接信息。

4. 创建RESTful API控制器:

创建一个控制器类来处理RESTful API请求,并实现以下功能:

  • 提交动态脚本并执行
  • 缓存已实例化的Groovy对象到Redis
  • 检查是否已存在相同脚本,并直接调用已实例化的Groovy对象执行

示例控制器代码:

@RestController
@RequestMapping("/scripts")
public class RuleScriptController {
    private final RedisTemplate<String, RuleScript> redisTemplate;

    public RuleScriptController(RedisTemplate<String, RuleScript> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @PostMapping
    public String executeScript(@RequestBody String scriptContent) throws CompilationFailedException, IOException {
        // 检查Redis中是否已存在相同脚本
        if (redisTemplate.hasKey(scriptContent)) {
            // 直接从缓存中获取已实例化的Groovy对象并执行
            RuleScript script = redisTemplate.opsForValue().get(scriptContent);
            script.execute();
            return "执行缓存中的脚本";
        } else {
            // 尝试从Redis获取已实例化的Groovy对象
            RuleScript script = redisTemplate.opsForValue().get(scriptContent);
            if (script == null) {
                // 缓存中不存在该脚本,需要编译并实例化新的Groovy对象
                script = compileAndInstantiateScript(scriptContent);
                // 将脚本对象缓存到Redis,以脚本内容作为键
                redisTemplate.opsForValue().set(scriptContent, script);
            }
            // 执行脚本
            script.execute();
            return "执行新的脚本";
        }
    }

    private RuleScript compileAndInstantiateScript(String scriptContent) throws CompilationFailedException, IOException {
        GroovyClassLoader classLoader = new GroovyClassLoader();
        Class<RuleScript> scriptClass = classLoader.parseClass(scriptContent);
        try {
            return scriptClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("无法实例化Groovy脚本", e);
        } finally {
            classLoader.close();
        }
    }
}

在上述代码中,我们使用RedisTemplate来操作Redis,并将其作为控制器的构造函数参数进行注入。

  • 在检查Redis中是否存在相同脚本时,我们先尝试直接从Redis获取已实例化的Groovy对象。如果存在,则直接执行缓存中的脚本,避免重复实例化GroovyClassLoader。
  • 如果Redis中不存在相同脚本,则调用compileAndInstantiateScript方法编译并实例化新的Groovy对象。编译完成后,将脚本对象缓存到Redis中,以脚本内容作为键。
  • 在compileAndInstantiateScript方法中,我们使用GroovyClassLoader进行脚本的编译和实例化。在实例化完成后,我们手动关闭GroovyClassLoader,以释放资源。
  • 异常处理:在实例化Groovy对象时,捕获InstantiationException和IllegalAccessException异常,并将其包装成运行时异常抛出。

5. 主应用程序类:

创建一个主应用程序类并在其中启动Spring Boot应用。

示例代码:

@SpringBootApplication
public class DynamicRuleApplication {
    public static void main(String[] args) {
        SpringApplication.run(DynamicRuleApplication.class, args);
    }

    @Bean
    public RedisTemplate<String, RuleScript> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, RuleScript> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new Jackson2JsonRedisSerializer<>(RuleScript.class));
        return template;
    }
}

在上述代码中,我们使用@Bean注解创建了一个名为redisTemplateRedisTemplate实例,并配置了键和值的序列化方式。键使用StringRedisSerializer进行序列化,值使用Jackson2JsonRedisSerializer,并指定了值的类型为RuleScript

  1. 编译并运行应用程序:
    完成以上步骤后,使用构建工具(如Maven或Gradle)编译项目,并运行Spring Boot应用程序。

  2. 测试API:
    使用任何HTTP客户端(如Postman)发送POST请求到/scripts路径,并在请求体中传递动态脚本内容。

示例请求:

URL: POST http://localhost:8080/scripts
Body:

"class RuleScript {
	def execute() {
		println('执行动态规则')
		}
	}
"

根据请求的不同,应用程序将执行以下操作:

  • 如果缓存中存在相同的脚本,直接从缓存中获取已实例化的Groovy对象并执行。
  • 如果缓存中不存在相同的脚本,将编译新的Groovy脚本并实例化对象,然后执行脚本并缓存到Redis。

总结

通过以上步骤,我们实现了一个基于Spring Boot集成Groovy Script的动态规则解析和执行的Demo。脚本提交后将被缓存到Redis,并在下次提交相同脚本时直接调用已实例化的Groovy对象进行执行,提高了执行效率。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot 集成 Groovy Script 完整示例 的相关文章

  • 如何使用 Java 创建多个模式连接?

    我必须使用两个数据库 DB2 Oracle 我在 DB2 数据库中有一个名为NAVID 我想使用 Java 为 Oracle 中的所有表创建相同的架构 public class automateExport static String va
  • Java中定义类型后同时初始化多个变量?

    这里需要一些语法方面的帮助 我正在尝试在定义类型后重新初始化多个变量 例如 int bonus sales x y 50 这工作正常 但是我想稍后在程序中将不同的值放入其中一些变量中 但我收到语法错误 bonus 25 x 38 sales
  • Maven 目标的默认阶段?

    据我了解 在 Maven 中 插件目标可以附加到生命周期阶段 如果没有定义 默认阶段是什么 根据我的经验 这取决于插件的目标 例如 组装 单个 http maven apache org plugins maven assembly plu
  • 空 EntityManager/EJB 注入 MDB

    我有一个消息驱动 bean MDB 部署到 WebLogic 12 1 3 我尝试使用 PersistenceContext 注释将实体管理器注入 MDB 但实体管理器为空 我还尝试注入一个简单的无状态会话 bean 它也是空的 但是 Me
  • 为什么一个线程会中断另一个线程[重复]

    这个问题在这里已经有答案了 在Java多线程应用程序中 我们处理InterruptedThreadException 如果另一个线程中断当前线程 则会抛出此异常 现在 当另一个线程知道它将导致异常时 它可能想要中断当前线程的原因是什么 很多
  • BigDecimal 的 JPA @Size 注释

    我该如何使用 SizeMySQL 的注释DECIMAL x y 列 我在用着BigDecimal 但是当我尝试包括 Size max它不起作用 这是我的代码 Size max 7 2 Column name weight private B
  • 此版本不符合 Google Play 64 位要求,添加库后仍然出现错误

    我正在 Play 商店上传一个视频编辑器应用程序 其中包含带有一些本机代码的库 所以我通过将其添加到 gradle 来使其兼容 64 位 ndk abiFilters armeabi v7a arm64 v8a x86 x86 64 添加了
  • 带有面板的 Java Swing JToolbar:外观和感觉

    我有一个JToolbar其中包含多个JPanels 需要 因为我希望每个都有特定的边界 不幸的是 外观管理器无法识别JPanels属于工具栏和JButtons因此 渲染器与普通按钮一样 即没有工具栏上的特殊鼠标悬停效果 更换JPanels
  • 更改 JTextPane 的大小

    我是Java新手 刚刚在StackOverflow中找到了这段代码 ResizeTextArea https stackoverflow com questions 9370561 enabling scroll bars when jte
  • 如何使用 BufferedReader 对象从 Java 中的一行读取多个整数值?

    我正在使用 BufferedReader 类读取 Java 程序中的输入 我想读取用户的输入 该用户可以在带空格的单行中输入多个整数数据 我想读取整数数组中的所有这些数据 输入格式 用户首先输入他 她想要输入的数字数量 然后在下一行中使用多
  • MessageDigest MD5 算法未返回我期望的结果

    我脑后的某个东西告诉我 我在这里遗漏了一些明显的东西 我正在将现有的 java 项目与第三方 api 集成 该第三方 api 使用 api 密钥的 md5 哈希进行身份验证 它对我不起作用 在调试过程中我意识到我生成的哈希值与他们提供的示例
  • 更改 RowLayout SWT Java 中元素的顺序

    有没有办法更改在行布局中创建的元素的顺序 我想将其显示在元素中 首先显示 例如 如果我创建 element1 则 element2 element3 element4 我想看到的布局为 元素4 元素3 元素2 元素1 这意味着最后创建的元素
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • setKeyListener 将覆盖 setInputType 并更改键盘

    大家好 我在两个设备之间遇到问题 在实践中使用InputType和KeyListener我正在操纵一个EditText让它从数字键盘接收逗号和数字 有关更多背景信息 请检查我之前的question https stackoverflow c
  • 如何使用 Hibernate Session.doWork(...) 进行保存点/嵌套事务?

    我正在使用 JavaEE JPA 托管事务与 Oracle DB 和 Hibernate 并且需要实现某种嵌套事务 据我所知 此类事情不受开箱即用的支持 但我应该能够为此目的使用保存点 正如建议的https stackoverflow co
  • Jenkins 管道和 java.nio.file.* 方法的问题

    我正在尝试使用 java nio file 中的方法在 Jenkins 管道中执行一些基本文件操作 无论代码存在于哪个节点块中 代码都在主节点上执行 在管道中 我已经验证了各个节点块都是正确的 它们唯一地标识了特定的节点 但是 pathEx
  • 如何使用maven创建基于spring的可执行jar?

    我有一个基于 Maven 的 Spring WS 客户端项目 我想将其打包为单个 jar 在eclipse中 一切运行正常 当我尝试将其打包为可执行 jar 时 我收到 ClassNotFound 异常 因为 Spring jar 未包含在
  • 无法在 BlackBerry Playbook 上设置音量

    我在更改黑莓游戏书的音量时遇到问题 首先 我将 Android 应用程序重新打包到 Palybook 应用程序 我需要使用搜索栏更改黑莓剧本的音量 并在搜索监听器中设置音频管理器音量 这是代码 audioManager AudioManag
  • 当我在 Java 中输入 IP 时无法连接到我的服务器

    好的 我正在尝试学习 Java 客户端 服务器的内容 并且正在浏览教程代码 如下所示 当我将 localhost 更改为我的 IP 时 它会停止工作 请帮忙 编辑 127 0 0 1 似乎也可以工作 但不是我的真实IP Copyright
  • 在多线程环境中,Collections.sort 方法有时会抛出 ConcurrentModificationException。列表没有进行结构性修改

    package CollectionsTS import java util ArrayList import java util Collections import java util HashSet import java util

随机推荐

  • TS实现原生数组方法之遍历:filter()

    function Array prototype filter description 循环遍历数组每个元素筛选出符合给定条件的元素组成的数组 param callback callback三个参数 1 当前值 2 当前索引 可选 3 当前
  • HashMap多个构造方法的理解

    1 创建HashMap除了常用的空方法 Map map new HashMap 2 还有一个入参的 这个入参并不是指创建大小为3的HashMap 而是创建大于3的最小2的n次方大小的HashMap 比如3 实际创建的长度为2 2 4 以此类
  • 一文打通ER图(手把手教你画)

    目录 什么是er图 什么是实体类型 什么是属性 什么是联系 一对一 一对多 多对多 注意点 例题解答 期末了 E R图也是大学课程设计中经常用到的 也是期末考的重点 毕竟大学生也没什么好考的 最近也有不少同学问 不少单子也扯到E R图 但是
  • 你还好吗

    最近突发奇想 假如某一天 我不在 这一行干了 那我又该去找什么样的工作 又该何去何从 活了二十几年 也没培养出什么兴趣爱好 也没什么特长优点 迷茫的人生 迷茫的我 我想听听你们的意见
  • openGauss学习笔记-09 openGauss 简单数据管理-创建数据库

    文章目录 openGauss学习笔记 09 openGauss 简单数据管理 创建数据库 9 1 语法格式 9 2 参数说明 9 3 示例 openGauss学习笔记 09 openGauss 简单数据管理 创建数据库 数据库安装完成后 默
  • 【爬虫进阶】猿人学任务六之回溯(难度3.0)

    目录 前言 分析 扣代码 Js改写 代码过程 结果 前言 本文讲解猿人学web题目第6题 内容难点如下 颜文字 JSUnFuck 分析 打开题目网站 F12 点击XHR 找出数据接口 看到请求参数这里 m是加密的 q是两个时间戳 全局搜索加
  • FindBugs错误修改指南

    1 EC UNRELATED TYPES Bug Call to equals comparing different types Pattern id EC UNRELATED TYPES type EC category CORRECT
  • 圆盘找数

    任务 三 圆盘找数 一 目的与要求 1 目的 使学生掌握数组的概念 阅读 编写和调试数组的要领 通过本实训可加深对于数组 最大值 最小值的理解和加强数组处理 分类求值 最大 小 值得求法等比较技术编程能力的训练 2 要求 1 根据问题域设计
  • VBA中的Application.Calculation,公式的计算方式

    VBA经典应用69例 10178981 是我推出的第九套教程 教程是专门针对初级 中级学员在学习VBA过程中可能遇到的案例展开 这套教程案例众多 紧贴 实战 并做 战术总结 以便大家能很好的应用 教程的目的是要求大家在实际工作中要利用好VB
  • 目标检测论文解读复现之六:基于YOLOv5的遥感图像舰船的检测方法

    目标检测论文解读复现 文章目录 目标检测论文解读复现 前言 一 摘要 二 网络模型及核心创新点 三 应用数据集 四 实验效果 五 实验结论 六 投稿期刊介绍 前言 此前出了目标改进算法专栏 但是对于应用于什么场景 需要什么改进方法对应与自己
  • 【实战】Python爬虫之代理使用详解

    在Python爬虫中 代理的使用非常常见 代理的主要作用是隐藏客户端的真实IP地址 从而实现更高的网络访问速度和更好的访问隐私保护 下面我们将通过Python爬虫的实例 带你详细了解Python爬虫中代理的使用方法 目录 1 代理原理和作用
  • 随机生成小球(万家灯火的感觉)

    事发年前 新冠之前 拿到一张psd 全部静态 老板说想让他动起来 在我们这种老板吃死技术的小公司只能自己想办法 你想要ui no我们只有美工哈哈哈 独立自强的我瞬间想到transition enter leave cubic bezier之
  • 利用Python进行心脏病患者特征分析

    今天要跟大家说到的一个数据集分析 是关于心脏病的 心脏病作为全球第一大杀手 是我们不得不提前防御的疾病 今天我们利用Python从一份心脏病数据集中找出一些规律 看下哪些特征对于确诊心脏病影响比较大 从而提醒我们注意平时的生活规律 数据集介
  • 解决报错error resource androidattrdialogCornerRadius not found

    解决报错error resource android attr dialogCornerRadius not found 1 问题描述 运行Android Studio程序 产生报错error resource android attr d
  • 计算机大三学生怎么找实习工作?学了计算机很迷茫怎么办?

    学了计算机很迷茫怎么办呢 很多计算机大三学生找不到实习工作 也不知道从哪找实习工作 甚至常常怀疑自己的学习有没有意义 今日就由小编为大家简要介绍下吧 学了计算机很迷茫怎么办 学了计算机很迷茫怎么办呢 经常有很多学生发生这样的感慨 事实上绝大
  • sklearn中的fit_transform和transform以及什么时候使用

    在使用sklearn对数据进行预处理的时候很有可能会遇到fit transform和transform 网上不少资料写的模棱两可 在这里我回答几个核心问题 也许看完我写的这篇文章 一些疑惑就会豁然开朗 为什么在训练集进行fit而不在测试集f
  • c++的并归排序怎么写

    答 C 的并归排序的写法如下 1 如果数组只有一个元素 则返回该元素 2 否则 将数组分成两半 3 使用递归 对每一半进行并归排序 4 将排序后的两个子数组合并 5 返回排序后的结果
  • C语言回调函数一个简单的例子

    回调函数通俗的解释 普通函数 你所写的函数调用系统函数 你只管调用 不管实现 回调函数 系统调用你所写的函数 你只管实现 不管调用 以下是使用 语言实现回调函数的一个例子 代码 include
  • Microsoft Excel 无法插入新的单元格,因为这会将非空单元格推送到工作表的末尾...的问题解决

    这个问题的出现应该是最后一行或一列有数据 按以下步骤操作 1 选中文字表格最后一列空白列 随后按ctrl shift 向右 选中整列 点击右键删除 2 选中文字表格最后一行空白列 随后按ctrl shift 向右 选中整行 点击右键删除
  • Springboot 集成 Groovy Script 完整示例

    Springboot 集成 Groovy Script 完整示例 使用Spring Boot集成Groovy Script来实现动态规则解析和执行的Demo 以下是实现步骤 1 创建Spring Boot项目 首先 创建一个Spring B