当前位置: 首页 > article >正文

LiteFlow 流程引擎引入Spring boot项目集成pg数据库

文章目录

    • 官网地址
    • 简要
    • 项目引入
        • maven 所需jar包
        • 配置 PostgreSQL 数据库表使用LiteFlow
            • 配置 yml 文件
            • 通过 代码方式使用 liteflow
            • 数据库sql
    • 数据在流程中周转

在这里插入图片描述

官网地址

https://liteflow.cc/

简要

如果你要对复杂业务逻辑进行新写或者重构,用LiteFlow最合适不过。它是一个编排式的规则引擎框架,组件编排,帮助解耦业务代码,让每一个业务片段都是一个组件。
利用LiteFlow,你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构,这种结构的好处是可以任意编排,组件与组件之间是解耦的,组件可以用脚本来定义,组件之间的流转全靠规则来驱动。LiteFlow拥有开源规则引擎最为简单的DSL语法。十分钟就可上手。
LiteFlow的脚本组件,支持众多脚本语言,完全和Java打通,你可以用脚本来实现任何逻辑。
在这里插入图片描述

项目引入

maven 所需jar包
  • liteflow-spring-boot-starter:
    • 这是 LiteFlow 的核心依赖,它集成了 LiteFlow 与 Spring Boot 框架,使得你可以轻松地在 Spring Boot 项目中使用 LiteFlow 来进行流程管理。
  • liteflow-rule-sql:
    • 此模块提供了从 SQL 数据库加载规则的能力,使你可以将流程定义存储在数据库中,并根据需要动态加载它们。
  • liteflow-script-groovy:
    • 该依赖项允许你在 LiteFlow 中使用 Groovy 脚本语言来编写脚本节点。Groovy 是一种强大的动态语言,非常适合编写简短而灵活的脚本逻辑。
  • liteflow-script-javax:
    • 提供了使用 Java 编写的脚本节点支持,允许更深入地集成业务逻辑。
  • liteflow-script-aviator:
    • Aviator 是一个轻量级的表达式语言引擎,这个依赖允许你在 LiteFlow 中使用 Aviator 表达式来简化条件判断和其他逻辑操作。
<properties>
	<liteflow.version>2.12.4.1</liteflow.version>
</properties>
<dependencies>
	<dependency>
		<groupId>io.springfox</groupId>
		<artifactId>springfox-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>com.yomahub</groupId>
		<artifactId>liteflow-spring-boot-starter</artifactId>
		<version>${liteflow.version}</version>
	</dependency>
	<dependency>
		<groupId>com.yomahub</groupId>
		<artifactId>liteflow-rule-sql</artifactId>
		<version>${liteflow.version}</version>
	</dependency>
	<dependency>
		<groupId>com.yomahub</groupId>
		<artifactId>liteflow-script-groovy</artifactId>
		<version>${liteflow.version}</version>
	</dependency>

	<dependency>
		<groupId>com.yomahub</groupId>
		<artifactId>liteflow-script-javax</artifactId>
		<version>${liteflow.version}</version>
	</dependency>

	<dependency>
		<groupId>com.yomahub</groupId>
		<artifactId>liteflow-script-aviator</artifactId>
		<version>${liteflow.version}</version>
	</dependency>
</dependencies>
配置 PostgreSQL 数据库表使用LiteFlow
配置 yml 文件

rule-source-ext-data-map

  • 这部分定义了 LiteFlow 如何从外部数据源加载规则信息。具体来说:
  • applicationName: 应用名称,这里是 dataprocessing,它用于标识当前应用。
  • chainTableName: 规则链表名,即 sys_rule_chain,LiteFlow 将从此表中读取规则链信息。
  • 字段映射:
  • chainApplicationNameField: 表示规则链所属的应用名称字段,这里为 application_name。
  • chainNameField : 规则链名称字段,对应 chain_name。
  • elDataField : 表达式数据字段,即 el_data,通常用于存储条件表达式或执行逻辑。
  • routeField : 路由字段,表示 route。
  • namespaceField : 命名空间字段,对应 namespace。
  • chainEnableField : 启用状态字段,表示 enable,用于控制是否启用该规则链。
  1. Script 表配置(可选)
  • 如果你的应用使用脚本来增强规则链的功能,可以配置这些选项:
  • scriptTableName : 脚本表名,这里是 sys_rule_script。
  • scriptIdField, scriptNameField, scriptDataField, scriptTypeField, scriptLanguageField, scriptEnableField `: 分别指定了脚本 ID、名称、数据(内容)、类型、语言和启用状态的字段名。
    1. 轮询机制
  • pollingEnabled : 设置为 true 表示启用了轮询机制,LiteFlow 将定期检查是否有新的或更新的规则需要加载。
  • pollingStartSeconds : 定义首次轮询开始的时间点,设置为 0 意味着服务启动后立即开始第一次轮询。
  • pollingIntervalSeconds: 定义两次轮询之间的间隔时间,这里是每5秒一次。
    1. 解析模式 (parse-mode)
  • parse_one_on_first_exec: 这个模式意味着当一个链首次被执行时,LiteFlow 会解析该链,并在后续执行中使用缓存的结果。只有当检测到有变更时(如通过轮询发现),才会重新解析。
liteflow:
  rule-source-ext-data-map:
    applicationName: demo
    #以下是chain表的配置,这个一定得有
    chainTableName: chain
    chainApplicationNameField: application_name
    chainNameField: chain_name
    elDataField: el_data
    routeField: route
    namespaceField: namespace
    chainEnableField: enable
    #以下是script表的配置,如果你没使用到脚本,下面可以不配置
    scriptTableName: script
    scriptApplicationNameField: application_name
    scriptIdField: script_id
    scriptNameField: script_name
    scriptDataField: script_data
    scriptTypeField: script_type
    scriptLanguageField: language
    scriptEnableField: enable
    #以下是轮询机制的配置
    pollingEnabled: true
    pollingStartSeconds: 0
    pollingIntervalSeconds: 5
  parse-mode: parse_one_on_first_exec
通过 代码方式使用 liteflow

@LiteflowComponent 是 LiteFlow 框架中的一个注解,用于标识一个类为 LiteFlow 组件。这个注解类似于 Spring 框架中的 @Component 注解,但它具有特定于 LiteFlow 的功能和用途。
a,b,c, d 代码实例

@LiteflowComponent("a")
public class ACmp extends NodeComponent {

	@Override
	public void process() {
		System.out.println("ACmp executed!");
	}
}

@LiteflowComponent("b")
public class BCmp extends NodeComponent {

	@Override
	public void process() {
		System.out.println("BCmp executed!");
	}

}
@LiteflowComponent("c")
public class CCmp extends NodeComponent {

	@Override
	public void process() {
		System.out.println("CCmp executed!");
	}

}

@LiteflowComponent("d")
public class DCmp extends NodeComponent {

	@Override
	public void process() {
		System.out.println("DCmp executed!");
	}

}
数据库sql
create table chain
(
    id               bigint auto_increment
        primary key,
    application_name varchar(32) null,
    chain_name       varchar(32) null,
    chain_desc       varchar(64) null,
    el_data          text        null,
    route            text        null,
    namespace        varchar(32),
    create_time      datetime    null,
    enable           tinyint(1)  1
);


create table script
(
    id               bigint auto_increment
        primary key,
    application_name varchar(32) null,
    script_id        varchar(32) null,
    script_name      varchar(64) null,
    script_data      text        null,
    script_type      varchar(16) null,
    language         varchar(32) null,
    enable           tinyint(1)  1
);

INSERT INTO chain (id, application_name, chain_name, chain_desc, el_data, route, namespace, create_time, enable) VALUES (1, 'demo', 'chain1', '测试流程', 'THEN(a,b,c,s1,s2,s3,s4);', null, null, '2022-09-19 19:31:00', 1);
INSERT INTO chain (id, application_name, chain_name, chain_desc, el_data, route, namespace, create_time, enable) VALUES (3, 'demo', 'r_chain1', '策略路由1', 'THEN(b,a,s1);', 'r1', 'ns', '2024-05-27 14:03:01', 1);
INSERT INTO chain (id, application_name, chain_name, chain_desc, el_data, route, namespace, create_time, enable) VALUES (4, 'demo', 'r_chain2', '策略路由2', 'THEN(a,b,s2);', 'OR(r1,r2)', 'ns', '2024-05-27 14:03:44', 1);

INSERT INTO script (id, application_name, script_id, script_name, script_data, script_type, language, enable) VALUES (1, 'demo', 's1', '脚本s1', 'import cn.hutool.core.date.DateUtil

def date = DateUtil.parse("2022-10-17 13:31:43")
println(date)
defaultContext.setData("demoDate", date)

class Student {
   int studentID
   String studentName
}

Student student = new Student()
student.studentID = 100301
student.studentName = "张三"
defaultContext.setData("student",student)

def a=3
def b=2
defaultContext.setData("s1",a*b)', 'script', 'groovy', 1);
INSERT INTO script (id, application_name, script_id, script_name, script_data, script_type, language, enable) VALUES (2, 'demo', 's2', '脚本s2', 'defaultContext.setData("s2","hello")', 'script', 'groovy', 1);
INSERT INTO script (id, application_name, script_id, script_name, script_data, script_type, language, enable) VALUES (3, 'demo', 's3', '脚本s3', 'setData(defaultContext, "s3", 5*6);', 'script', 'aviator', 1);
INSERT INTO script (id, application_name, script_id, script_name, script_data, script_type, language, enable) VALUES (4, 'demo', 's4', '脚本4', 'import cn.hutool.core.collection.ListUtil;
            import com.yomahub.liteflow.script.body.CommonScriptBody;
            import com.yomahub.liteflow.slot.DefaultContext;
            import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
            import com.example.liteflow.mysql.vo.Person;
            import com.yomahub.liteflow.script.ScriptExecuteWrap;
            import java.util.List;
            import java.util.function.ToIntFunction;

            public class Demo implements CommonScriptBody {
                public Void body(ScriptExecuteWrap wrap) {
                    DefaultContext ctx = wrap.getCmp().getFirstContextBean();
                    List<Person> personList = ListUtil.toList(
                            new Person("jack", 15000),
                            new Person("tom", 23500),
                            new Person("peter", 18500)
                    );

                    int totalSalary = personList.stream().mapToInt(Person::getSalary).sum();

                    System.out.println(totalSalary);
                    ctx.setData("salary", totalSalary);

                    return null;
                }
            }', 'script', 'java', 1);

数据在流程中周转

liteflow 是进行流程上下文的方式去 读取存储数据
我们在组件里面写业务,首先肯定就是要拿到上下文,在声明式组件里通常的写法为:

@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS,nodeType = NodeTypeEnum.COMMON, nodeId = "b")
public void processB(NodeComponent bindCmp) {
    YourContext context = bindCmp.getContextBean(YourContext.class);
    //从context中取到业务数据进行处理
    User user = context.getUser();
    ...
}

具体参考官网 https://liteflow.cc/pages/8777f8/


http://www.kler.cn/a/460660.html

相关文章:

  • 选择器(结构伪类选择器,伪元素选择器),PxCook软件,盒子模型
  • 活动预告 |【Part2】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识
  • 【PCIe 总线及设备入门学习专栏 4.5 -- PCIe Message and PCIe MSI】
  • 二十三种设计模式-工厂方法模式
  • 将现有Web 网页封装为macOS应用
  • httpslocalhostindex 配置的nginx,一刷新就报404了
  • 初始JavaEE篇 —— Maven相关配置
  • (echarts)ECharts折线图堆叠设置为不堆叠的方法
  • 华为消费级QLC SSD来了
  • TCP粘/拆包----自定义消息协议
  • Python 的 abc 模块 抽象基类(Abstract Base Classes)
  • 建造者模式详解
  • Java - 日志体系_Apache Commons Logging(JCL)日志接口库_桥接Logback 及 源码分析
  • 04、JUC并发编程之:简单概述(四)
  • pg_wal 目录下 wal 日志文件异常累积过大
  • 慧眼识词:解析TF-IDF工作原理
  • python爬虫--小白篇【selenium自动爬取文件】
  • 微信小程序自定义表格样式
  • 2024年度总结
  • 前端多个项目部署在同一个nginx下,前缀不同,配置编写方式
  • 红黑树的左旋右旋
  • MySQL 执行计划:优化查询性能
  • 家政预约小程序04活动管理表结构设计
  • Mac安装Jupyter和nbextensions报错问题
  • OpenStack系列第四篇:云平台基础功能与操作(Dashboard)
  • Spring 创建和管理 Bean 的原理,以及Spring 的单例模式是否线程安全?(有无状态Bean)