工作流 Flowable

工作流包括业务流和审批流等业务流程。

在一个流程系统中,任务间往往存在复杂的依赖关系,为保证pipeline的正确执行,就是要解决各任务间依赖的问题,这样DAG结合拓扑排序是解决存在依赖关系的一类问题的利器。DAG ( Directed Acyclic Graph),有向无环图,是指任意一条边有方向,且不存在环路的图。如果把依赖关系的问题建模成 DAG, 依赖关系成为 Graph 中的 Directed Edge, 然后通过拓扑排序,不断遍历和剔除无依赖的节点(无前置节点的节点),可以达到快速解决依赖的目的。

Flowable 工作流使用

Flowable 项目中包括 BPMN(Business Process Model and Notation)引擎、CMMN(Case Management Model and Notation)引擎、DMN(Decision Model and Notation)引擎、表单引擎(Form Engine)等模块。也有许多Flowable 应用(Flowable Modeler、Flowable Admin、Flowable IDM 与 Flowable Task),并提供了直接可用的 UI 示例。

官方文档:https://tkjohn.github.io/flowable-userguide/#_introduction

0.首先需要初始化ProcessEngine流程引擎实例。这是一个线程安全的对象,因此通常只需要在一个应用中初始化一次。 ProcessEngine由ProcessEngineConfiguration实例创建。该实例可以配置与调整流程引擎的设置。

通常使用一个配置XML文件创建ProcessEngineConfiguration,如果是springboot项目直接在yml中配置数据源即可,启动时会自动实例化到ioc容器中,无需flowable.cfg.xml文件。 ProcessEngineConfiguration所需的最小配置,是数据库JDBC连接.

比如通过xml文件创建:可以在 resources 目录下创建一个 flowable.cfg.xml 文件

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration"><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/flow1?allowMultiQueries=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=UTC&amp;nullCatalogMeansCurrent=true" /><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" /><property name="jdbcUsername" value="root" /><property name="jdbcPassword" value="123456" /><property name="databaseSchemaUpdate" value="true" /><property name="asyncExecutorActivate" value="false" /></bean>
</beans>

然后就可以直接获取流程引擎对象了: ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

Springboot集成

1.pom.xml添加依赖

  <!-- SpringBoot整合flowable --><dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.6.0</version></dependency>

2.application.yml 配置数据源

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/flowable-boot?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456
flowable:async-executor-activate: false # 关闭定时任务# 将databaseSchemaUpdate 设置为 true。当Flowable发现库与数据库表结构不一致时,会自动将数据库表结构升级至新版本database-schema-update: true

3.配置好后直接启动,服务就会自动初始化数据库,增加需要的表。所有的Flowable服务都暴露为Spring bean

@Resource
private ProcessEngine processEngine; // // 直接注入ProcessEngine 对象
// 以下四个模块的服务接口可以直接注入使用,也可以通过ProcessEngine获取
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;

另外resources/processes目录下的任何BPMN 2.0流程定义都会被自动部署。

resources/cases目录下的任何CMMN 1.1事例都会被自动部署。

resources/forms目录下的任何Form定义都会被自动部署。

4.创建bpmn20.xml文件

在resources下创建processes目录,并在其中创建示例流程定义(命名为holiday-request.bpmn20.xml) .bpmn20.xml是文件后缀名

 开始事件:图中用细线圆圈来表示,是流程实例的开始点

 箭头:表示节点之间的流转指向。

 用户任务: 在图中用左上角有人的圆角矩形表示,这些是需要用户来操作的节点。图中有两个,第一个表示需要经理进行审批来同意或拒绝,第二个表示用户来确认销假。

 排它网关: 用叉形符号填充的菱形表示,从该图中出来的箭头往往有多个,但只有一个满足条件,流程会沿着满足条件的方向流转。

 自动化任务 :左上角有齿轮形状的的圆角矩形,表示自动执行的节点。图中上面的表示请假被经理同意后自动注册通知到外部系统,下面的表示请假被经理拒绝后自动发邮件通知给申请人。

 结束事件: 图中用粗线圆圈表示,表示流程的结束。图中上面的结束事件表示请假成功结束,下面的表示请假失败结束。

一般来说,这样的流程定义使用可视化建模工具建立,如Flowable Designer(Eclipse)或 flowable-ui-modeler(flowable-ui Web应用),保存后可得到bpmn20.xml格式文件

FlowableUI 流程设计器

Flowable 提供了几个 web 应用,用于演示及介绍 Flowable 项目提供的功能:

Flowable IDM: 身份管理应用。为所有 Flowable UI 应用提供单点登录认证功能,并且为拥有IDM管理员权限的用户提供了管理用户、组与权限的功能。

Flowable Modeler: 让具有建模权限的用户可以创建流程模型、表单、选择表与应用定义。

Flowable Task: 运行时任务应用。提供了启动流程实例、编辑任务表单、完成任务,以及查询流程实例与任务的功能。

Flowable Admin: 管理应用。让具有管理员权限的用户可以查询 BPMN、DMN、Form 及 Content 引擎,并提供了许多选项用于修改流程实例、任务、作业等。管理应用通过 REST API 连接至引擎,并与 Flowable Task 应用及 Flowable REST 应用一同部署。

所有其他的应用都需要 Flowable IDM 提供认证。每个应用的 WAR 文件可以部署在相同的 servlet 容器(如Apache Tomcat)中,也可以部署在不同的容器中。由于每个应用使用相同的 cookie 进行认证,因此应用需要运行在相同的域名下。

可以使用docker快速部署。

Flowable UI默认的登录用户名是 admin,默认的登录密码是 test。

resources/processes/holiday-request.bpmn20.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"xmlns:flowable="http://flowable.org/bpmn"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.flowable.org/processdef"><process id="holidayRequest" name="Holiday Request" isExecutable="true"><startEvent id="startEvent"/><sequenceFlow sourceRef="startEvent" targetRef="approveTask"/><userTask id="approveTask" name="Approve or reject request"/><sequenceFlow sourceRef="approveTask" targetRef="decision"/><exclusiveGateway id="decision"/><sequenceFlow sourceRef="decision" targetRef="externalSystemCall"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${approved}]]></conditionExpression></sequenceFlow><sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression></sequenceFlow><serviceTask id="externalSystemCall" name="Enter holidays in external system"flowable:class="org.flowable.CallExternalSystemDelegate"/><sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/><userTask id="holidayApprovedTask" name="Holiday approved"/><sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/><serviceTask id="sendRejectionMail" name="Send out rejection email"flowable:class="org.flowable.SendRejectionMail"/><sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/><endEvent id="approveEnd"/><endEvent id="rejectEnd"/></process>
</definitions>

(1)每一个步骤(在BPMN 2.0术语中称作活动(activity))都有一个id属性,为其提供一个在XML文件中唯一的标识符。所有的活动都可以设置一个名字,以提高流程图的可读性。

 (2)活动之间通过顺序流(sequence flow)连接,在流程图中是一个有向箭头。在执行流程实例时,执行(execution)会从启动事件沿着顺序流流向下一个活动。

 (3)离开排他网关(带有X的菱形)的顺序流很特别:都以表达式(expression)的形式定义了条件(condition) 。当流程实例的执行到达这个网关时,会计算条件,并使用第一个计算为true的顺序流。这就是排他的含义:只选择一个。当然如果需要不同的路由策略,可以使用其他类型的网关。

 这里用作条件的表达式为${approved},这是${approved == true}的简写。变量’approved’被称作流程变量(process variable)。流程变量是持久化的数据,与流程实例存储在一起,并可以在流程实例的生命周期中使用。

(4).在这个例子里,我们需要在特定的地方(当用户任务提交时,或者以Flowable的术语来说,完成(complete)时)设置这个流程变量,因为这不是流程实例启动时就能获取的数据。

相关api操作

在Flowable中,数据库事务扮演了关键角色,用于保证数据一致性,并解决并发问题。当调用Flowable API时,默认情况下,所有操作都是同步的,并处于同一个事务下。

常用的几个JAVA class类介绍:

l ProcessDefinition

 这个最好理解,就是流程的定义,也就相当于规范,每个 ProcessDefinition 都会有一个 id。

 l ProcessInstance

 这个就是流程的一个实例。简单来说,ProcessDefinition 相当于是类,而 ProcessInstance 则相当于是根据类 new 出来的对象。

 l Activity

 Activity 是流程标准规范 BPMN2.0 里面的规范,流程中的每一个步骤都是一个 Activity。

 l Execution

 Execution 的含义是流程的执行线路,通过 Execution 可以获得当前 ProcessInstance 当前执行到哪个 Activity了

 l Task

 Task 就是当前要做的工作。

5.部署流程定义(ProcessDefinition)

这里因为是放到了resources/processes目录下,所以启动项目时就自动部署了,无需在手动加载.bpmn20.xml并部署了。

将流程定义部署至Flowable引擎, 并可以通过API查询验证流程定义是否已经部署在引擎中:

@Resource
private ProcessEngine processEngine; // 获取 RepositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// deploy()完成流程的实际部署操作,会创建一个ProcessDefinition流程定义Deployment deploy = repositoryService.createDeployment().addClasspathResource("xxxx.bpmn20.xml").name("请假流程").deploy();//删除部署的流程repositoryService.deleteDeployment("45001", true); // true 会将流程下的任务也一并删除//查询流程定义是否已部署到引擎中ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("35001").singleResult();
// processDefinition.getDeploymentId()、getName()、getDescription()、getId()

6.启动流程实例[ProcessInstance]

启动流程实例,需要提供一些初始化流程变量。一般来说,可以通过呈现给用户的表单,或者在流程由其他系统自动触发时通过REST API,来获取这些变量。这个流程实例使用key启动。这个key就是BPMN 2.0 XML文件中设置的id属性 

在流程实例启动后,会创建一个执行(Execution),并将其放在启动事件上。从这里开始,这个执行沿着顺序流移动到审批的用户任务,并执行用户任务行为。用户任务是一个等待状态(wait state),引擎会停止执行,返回API调用处。通过taskService.complete()来完成用户任务的执行。

  // 获取启动流程的服务RuntimeService runtimeService = processEngine.getRuntimeService();// 构建流程变量Map<String, Object> variables = new HashMap<>();variables.put("employee", "wsy");variables.put("nrOfHolidays", 10);variables.put("description", "生病了,去医院");// 启动流程,getActivityId() 可以查看现在在流程的哪一个步骤(Activity)中
ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("holidayRequest", variables); //"holidayRequest"是.bpmn20.xml中 <process>的id
//holidayRequest.getProcessDefinitionId()、 getActivityId()、 getId()

7.执行任务Task

//查看流程任务Task:TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery().processDefinitionId("holidayRequest:1:45003") // 流程ID//.processDefinitionKey("holidayRequest") // 流程key.taskAssignee("王经理") // 任务处理人//.list();列出所有任务
.singleResult();
//task.getId() 、task.getAssignee()、getName()、getProcessDefinitionId()//执行任务Map<String, Object> map = new HashMap<>();map.put("approved", true);// 完成任务taskService.complete(task.getId(), map);

8.查看历史信息

  HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processDefinitionId("holidayRequest:1:45003").finished() // 查询的历史记录的状态是已经完成.orderByHistoricActivityInstanceEndTime().asc() // 指定按结束时间排序.list();for(HistoricActivityInstance history : list) {System.out.println(history.getActivityName()+":"+history.getAssignee()+"--"+history.getActivityId()+":"+history.getDurationInMillis()+"毫秒");}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3267418.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

免费【2024】springboot 毕业生学历证明系统

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Android AI应用开发:移动检测

基于Google ML模型的Android移动物体检测应用——检测、跟踪视频中的物体 A. 项目描述 ML Kit物体检测器可以对视频流进行操作&#xff0c;能够检测视频中的物体并在连续视频帧中跟踪该物体。 相机捕捉视频时&#xff0c;检测到移动物体并为其生成一个边界框&#xff0c;并分…

微信小程序-本地部署(前端)

遇到问题&#xff1a;因为是游客模式所以不能修改appID. 参考链接&#xff1a;微信开发者工具如何从游客模式切换为开发者模式&#xff1f;_微信开发者工具如何修改游客模式-CSDN博客 其余参考&#xff1a;Ego微商项目部署&#xff08;小程序项目&#xff09;&#xff08;全网…

Xstate inspect状态图的使用 和 原理

状态图的好处之一是&#xff0c;在将状态图组合在一起的过程中&#xff0c;您可以探索流程中所有可能的状态。这种探索将帮助您避免代码中的错误和错误&#xff0c;因为您更有可能涵盖所有可能发生的情况。 因为状态图是可执行的&#xff0c;所以它们既可以表现为图&#xff0…

K8s集群prometheus镜像配置非root用户执行导致监控页面targets无相关node信息监控

【问题描述】 K8s集群prometheus镜像配置非root用户执行导致监控页面targets无相关node信息监控 【问题记录】 在k8s容器集群来部署prometheus服务,实现对node节点的监控,但发现部署了prometheus后页面targets没有显示node信息,配置检查也是正确的 排查prometheus日志发现…

速递!OpenAI 凌晨发布 SearchGPT 进军 AI 搜索,正式与 Google、Perplexity 竞争

&#x1f431; 个人主页&#xff1a;TechCodeAI启航&#xff0c;公众号&#xff1a;TechCodeAI &#x1f64b;‍♂️ 作者简介&#xff1a;2020参加工作&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab; 优质专…

数据分析或处理中关于坐标系的一些事

通过对本文的阅读&#xff0c;你将获取坐标系的一些基础知识&#xff0c;以及学会如何使用pyproj实现地理数据的投影与转换。更重要的是&#xff0c;作为一个开发者&#xff0c;面对地理坐标系的图层数据&#xff0c;需要进行面积计算、距离量测、规则分块等需求时&#xff0c;…

成都哪一个新媒体产业园可以提供全方位的支持?全成都拥有最优质服务的园区在这!

成都市&#xff0c;作为中国西部的经济和文化中心&#xff0c;近年来在新媒体产业领域迅猛发展。众多新媒体产业园在这里拔地而起&#xff0c;为创新企业提供了丰富的资源和优质的服务。其中&#xff0c;位于成都金牛区的国际数字影像产业园尤为引人注目&#xff0c;作为园区运…

深入分析 Android ContentProvider (五)

文章目录 深入分析 Android ContentProvider (五)ContentProvider 的性能优化和实践案例1. 性能优化技巧1.1. 数据库索引优化示例&#xff1a;添加索引 1.2. 批量操作与事务管理示例&#xff1a;批量插入操作 1.3. 使用异步操作示例&#xff1a;使用 AsyncTask 进行异步查询 1.…

无人机图像目标检测技术详解

当前研究领域的热点之一。无人机搭载的高清摄像头能够实时捕获大量图像数据&#xff0c;对这些数据进行有效的目标检测对于军事侦察、环境监测、灾害救援等领域具有重要意义。本文将对无人机图像目标检测技术进行详解&#xff0c;包括图像处理技术、目标检测算法、关键技术应用…

通过IEC104转MQTT网关轻松接入阿里云平台

随着智能电网和物联网技术的飞速发展&#xff0c;电力系统中的传统IEC 104协议设备正面临向现代化、智能化转型的迫切需求。阿里云作为全球领先的云计算服务提供商&#xff0c;其强大的物联网平台为IEC 104设备的接入与数据处理提供了强大的支持。本文将深入探讨钡铼网关在MQTT…

springcloud接入seata管理分布式事务

下载安装包 链接: seata 配置seata-server 文件上传Linux解压 压缩包我放在/usr/local/seata中 tar -zxvf seata-server-2.0.0.tar.gz修改配置文件 设置nacos为注册和配置中心 进入文件夹 cd /usr/local/seata/seata/conf修改application.yml文件 ...... ...... cons…

Anaconda目录

安装目录 Anaconda 在默认情况下会安装到 C:\ProgramData\Anaconda3&#xff0c;而 conda 环境和包会安装在 C:\Users\username\.conda\ 目录下。 备注&#xff1a;我是在windows下安装 的Anaconda。我的安装目录是C:\Program Files\Anaconda3 pkgs目录 在以上两个目录下都有…

【React】组件:全面解析现代前端开发的基石

文章目录 一、什么是组件&#xff1f;二、组件的类型三、组件的生命周期四、状态管理五、属性传递六、组合与继承七、最佳实践 在现代前端开发中&#xff0c;React 已成为开发者构建用户界面的首选框架之一。React 的强大之处在于其组件化设计&#xff0c;允许开发者将 UI 拆分…

如何使用C#快速创建定时任务

原文链接&#xff1a;https://www.cnblogs.com/zhaotianff/p/17511040.html 使用Windows的计划任务功能可以创建定时任务。 使用schtasks.exe可以对计划任务进行管理&#xff0c;而不需要编写额外代码 这里掌握schtasks /CREATE 的几个核心参数就可以快速创建计划任务 /SC …

PGSQL学习-基础表结构

1 访问数据库 创建好数据库后&#xff0c;你可以有三种方式访问数据库 运行PostgreSQL的交互式终端程序&#xff0c;它被称为psql&#xff0c; 它允许你交互地输入、编辑和执行SQL命令。 使用一种已有的图形化前端工具&#xff0c;比如pgAdmin或者带ODBC或JDBC支持的办公套件…

云计算安全扩展要求解读

云计算简介&#xff1a; 一种全新网络服务方式&#xff0c;将传统的以桌面为核 心的任务处理转变为以网络为核心的任务处理&#xff0c; 利用互联网实现自己想要完成的一切处理任务&#xff0c; 使网络成为传递服务、计算力和信息的综合媒 介&#xff0c;真正实现按需计算、多…

高级及架构师高频面试题-基础型

1、设计模式有哪些原则&#xff08;待解释的更直白&#xff09; 单一职责原则&#xff1a;一个类或方法应只负责一项职责&#xff0c;避免一个类因为多个变化原因而改变。开闭原则&#xff1a;软件实体应对扩展开放&#xff0c;对修改封闭。比如要增加用户类别的时候可以新增一…

【C++】选择语句-多行if语句

语法格式 if(条件) {条件满足后执行的操作} else {条件不满足执行的操作} 下面是一个实例 #include<iostream> using namespace std;int main() {//选择结构 - 多行if语句//输入考试分数&#xff0c;如果考试分数大于600&#xff0c;视为考上一本大学&#xff0c;在屏…

C# dataGridView 去掉左边多出来空列

1.问题 在使用winform做界面程序时&#xff0c;dataGridView控件创建好后&#xff0c;左侧会多出一列为空&#xff0c;如何删除呢 2.解决方法 你可以在属性窗口中进行设置 如图&#xff1a; 将RowHeadersVisible 属性设置为False 或者代码设置 this.dataGridView1.RowHea…