flowable之三 启动一个流程并跟踪

news2024/11/17 22:37:00

1. 背景介绍

当我们部署一个流程并启动后,Flowable会按照既定流程定义及进行节点处理以及自动流转,从一个节点执行到下一个节点,直至结束。在此过程中,系统如何处理BPMN XML文件?节点如何进行流转?本文对flowable内部源码进行解析,挖掘其引擎原理。

2. 系统原理

2.1. 总览图

总览图

在这里插入图片描述

如上图所示为流程启动关键节点图,主要由以下几部分组成:

1. 启动命令封装(橙色部分)

主要功能:通过将bpmnXML格式文件解析为程序可执行的内存对象Process。 类似于 saga 事件驱动中的 event 。。

a. 获取流程定义 ProcessDefinition(通过入参<流程key or 流程id>找到对应的流程定义)

b. 加载解析bpmn.xml文件(工作流原始文件)

c. 生成bpmnModel(工作流描述)

d. 生成Process(工作流执行)

2. 命令执行器(蓝色部分)

主要功能:流程执行过程中会添加各种拦截器,其中最为核心的是CommandInvokerInterceptor

a. LogInterceptor:当日志级别为debug时,会输出启动日志

b. SpringTransactionInterceptor

  Spring事务管理,用户事务的doTransaction、commit、rollback

c. CommandContextInterceptor:执行SqlSession close方法,将数据进行持久化

d. TransactionContextInterceptor

e. BpmnOverrideContextInterceptor

f. CommandInvokerInterceptor:真正执行启动流程命令的拦截器

3. 节点流转(绿色部分)

主要功能:完成对流程节点的执行,及找到下一个可执行的节点,直至流程运行完成。其最核心的包括DefaulFlowableEngineAgenda,该类持有operations,通过对节点操作封装为不同的Operation,进行节点的流转。

2.2. 命令执行器(CommandExecutor)

Flowable是通过命令模式 + 责任链模式完成对操作的执行,flowable启动代码中,构造ProcessEngine时会调用 init()方法进行引擎初始化,如下图所示:

2.3 启动命令封装

启动命令通过入参的流程key or 流程定义id加载对应的流程定义数据后,初始化了启动operation操作,其核心源码如下:

  1. 调用new StartProcessInstanceCmd 生成启动命令
    在这里插入图片描述

  2. StartProcessInstanceCmd.execute() 方法定义如下:其首先获取流程定义ProcessDefinition,之后通过调用startProcessInstance启动流程。

流程定义数据来源于数据表:ACT_RE_PROCDEF,其是在流程部署时写入的,注意其字段deploymentId,在作为数据表ACT_GE_BYTEARRAY的外键,关联了 流程XML原始文件
在这里插入图片描述

  1. 在得到流程定义后,通过调用 ProcessInstanceHelper#createProcessInstance方法进行流程启动,注意在该方法中,通过调用 ProcessDefinitionUtil.getProcess 得到流程 Process

注意在之后,通过 process.getInitialFlowElement 方法得到流程初始节点。在之后构造 Execution 实体时,设置该初始节点。
在这里插入图片描述
在这里插入图片描述

4)在方法 ProcessInstanceHelper.startProcessInstance 中,通过调用CommandContextUtil.getAgenda(commandContext).planContinueProcessOperation(execution) 将当前实例添加到操作堆栈operations中。

       至此:完成了启动命令的初始化过程

在这里插入图片描述

2.4流程节点流转(重点)

2.4.1 节点流转核心节点图

在这里插入图片描述

重点:上图为节点流转图,节点流转的核心是AbstractAgenda,其默认的实现是 DefaultFlowableEngineAgenda

该类持有变量operations,operations是个一个堆栈,在流转过程中,通过DefaultFlowableEngineAgenda一系列操作可以

将不同的操作压入栈中,然后运转过程中,将每一个操作弹出栈进行命令的执行。这里的operation指默认实现了AbstractOperation的操作类,AbstractOperation的实现类如下所示:

比如要继续流转,则压入ContinueProcessOperation,需要结束流程则需要压入 EndExecutionOperation。

在这里插入图片描述

2.4.2. ContinueProcessOperation操作

ContinueProcessOperation操作对节点和顺序流分别作了处理,如下图所示:

在这里插入图片描述
像极了 saga 中的 router 和 handler

当前元素为节点时,执行如下主要操作:

1)标记节点开始

2)执行节点监听器

3)获取节点对应行为器

4)执行行为器

当无对应的行为器时,则创建 takeOutgoingSequenceFlowsOperation 操作

在这里插入图片描述
当前元素为顺序流时,执行如下主要操作:

1)找到当前元素后置元素,设置为当前执行元素

2)如果后置元素是节点,则直接执行

3)如果后置元素是顺序流,则构造ContinueProcessOperation操作

在这里插入图片描述

2.4.2.1. 节点行为器ActivityBehavior

如下图所示为行为器的实现类,从图中可以看到我们熟悉的StartEvent、NoneEvent及ServiceTask的实现类。
在这里插入图片描述
在行为器执行完成对应操作后,由行为器决定是否继续向后流转节点FlowNodeActivityBehavior默认提供了leave()方法,其内部主要是构造 TakeOutgoingSequenceFlowsOperation 继续流转节点

2.4.3. TakeOutgoingSequenceFlowsOperation操作

TakeOutgoingSequenceFlowsOperation的实现分别对节点和顺序流进行了操作,如下图所示:
在这里插入图片描述

当前元素为节点时:
1)首先标记当前节点执行完成

2)遍历后置顺序流元素,并计算顺序流表达式属性

3)当无有效的后置顺序流元素时,则构建EndExecutionOperation,压入栈中

4)存在有效的后置顺序流元素时,则遍历顺序流并且构造 ContinueProcessOperation操作,压入栈中

在这里插入图片描述
当前元素为顺序流时:

1)标记当前元素结束,构造ContinueProcessOperation操作,压入栈中
在这里插入图片描述

2.5 Example

下面以该流程为例,详细列出操作流转步骤:
在这里插入图片描述

其节点流转图如下:

详细步骤如下:

Step 1: 在流程启动初期,operations堆栈中压入ContinueProcessOperation操作,传入的execution的当前节点为开始节点

在这里插入图片描述

Step 2: 取出栈顶操作元素开始节点并执,首先进行节点开始持久化操作,之后调用节点行为类执行,开始节点的行为类是 NoneStartEventActivityBehavior,如下图所示为空操作,

其并没有实现execute()方法,还是复用了父类FlowNodeActivityBehavior的execute()方法,执行leave方法,压入TakeOutgoingSequenceOperation操作,此时execution的当前节点为开始节点

Step 3: 弹出栈顶TakeOutgoingSequenceOperation(开始节点),首先进行节点结束持久化操作,之后获取开始节点的后置可用分支,压入ContinueProcessOperation堆栈,

此时execution的当前节点为 开始节点-创建变量节点顺序流

Step 4: 取出栈顶ContinueProcessOperation(开始节点-创建变量节点顺序流) 并执行,其目标节点为 创建变量节点,开始执行,首先执行节点开始持久化操作,接着执行其行为类JavaDelegate,

执行完成后,压入TakeOutgoingSequenceOperation操作,此时execution的当前节点为创建变量节点

计算节点后置节点以及其他逻辑后,压入操作类,此时execution的当前节点为开始节点–>创建变量的连线。

Step 5: 弹出栈顶TakeOutgoingSequenceOperation(创建变量节点),首先进行节点结束持久化操作,之后获取创建变量节点的可用分支,压入ContinueProcessOperation堆栈,

此时此时execution的当前节点为创建变量节点-结束事件顺序流

Step 6: 弹出栈顶ContinueProcessOperation(创建变量节点-结束事件),其目标节点为结束事件,开始执行,首先进行节点开始持久化操作,接着执行其行为类 NoneEndEventActivityBehavior,如下图可得,

在这里插入图片描述

结束事件行为器构造了TakeOutgoingSequenceOperation操作,此时execution的当前节点为

结束事件节点

Step 7: 弹出栈顶TakeOutgoingSequenceOperation(结束节点),首先进行节点结束持久化操作,之后获取创建变量节点的可用分支,无可用分支,则构造 EndExecutionOperation,此时execution的当前节点为结束节点
在这里插入图片描述

Step 8: 弹出栈顶EndExecutionOperation(结束节点),执行相关结束操作

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

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

相关文章

衡兰芷若成绝响,人间不见周海媚(4k修复基于PaddleGan)

一代人有一代人的经典回忆&#xff0c;1994年由周海媚、马景涛、叶童主演的《神雕侠侣》曾经风靡一时&#xff0c;周海媚所诠释的周芷若凝聚了汉水之钟灵&#xff0c;峨嵋之毓秀&#xff0c;遇雪尤清&#xff0c;经霜更艳&#xff0c;俘获万千观众&#xff0c;成为了一代人的共…

柔性数组(结构体成员)

目录 前言&#xff1a; 柔性数组&#xff1a; 给柔性数组分配空间&#xff1a; 调整柔性数组大小&#xff1a; 柔性数组的好处&#xff1a; 前言&#xff1a; 柔性数组&#xff1f;可能你从未听说&#xff0c;但是确实有这个概念。听名字&#xff0c;好像就是柔软的数…

鸿蒙小车之多任务调度实验

说到鸿蒙我们都会想到华为mate60&#xff1a;遥遥领先&#xff01;我们一直领先&#xff01; 我们这个小车也是采用的是鸿蒙操作系统&#xff0c;学习鸿蒙小车&#xff0c;让你遥遥领先于你的同学。 文章目录 前言一、什么是任务&#xff1f;为什么要有任务二、任务的状态三、任…

Axure自定义元件

目录 1.processOne的使用 ​编辑2.自定义元件的使用、 2.1如何自定义一个元件 2.2使用自定义元件 导语&#xff1a; Axure是绘制原型图的软件&#xff0c;但是我们很多时候不知道&#xff0c;画哪一个板块&#xff0c;所以流程图的绘制也是非常重要的 1.processOne的使用…

一些好用的VSCode扩展

可以在扩展这里直接搜索需要的扩展&#xff0c;点击安装即可。 1.Chinese 中文扩展&#xff0c;就是说虽然咱们懂点英语&#xff0c;但还是中文看着方便 2.Auto Rename Tag 当你重命名一个HTML 标签时&#xff0c;会自动重命名与他配对的HTML 标签 当你选择h4这个标签时&…

如何解决Windows 11黑屏的问题,让电脑“重见光明”

本页介绍了经过测试并证明有效的常见Windows 11黑屏故障的所有修复程序。 本页上的提示和解决方案适用于所有Windows 11设备,从台式电脑和笔记本电脑到微软的Surface二合一设备。 是什么导致Windows 11黑屏死机 在使用Windows 11时,显示器或屏幕明显关闭,通常被称为Window…

YOLOv8 图片目标计数 | 特定目标进行计数

全类别计数特定类别计数如何使用 YOLOv8 进行对象计数 有很多同学留言说想学 YOLOv8 目标计数。那么今天这篇博客,我将教大家如何使用 YOLOv8 进行对象计数。YOLOv8 是一种非常强大的对象检测模型,它可以识别图像中的各种对象。我们将学习如何利用这个模型对特定对象进行计数…

【日常笔记】notepad++ 正则表达式基本用法

一、场景 二、正则表达式--语法 2.1、学习基本的匹配字符&#xff1a; 2.2、学习特殊字符和量词&#xff1a; 2.3、学习转义字符 2.4、学习分组和捕获 2.5、区分大小写 和 匹配整个单词 2.6、引用分组 三、实战 ▶ 希望把课程目录中 -- 前面的都去掉 一、场景 希望把…

如何使用ArcGIS Pro裁剪影像

对影像进行裁剪是一项比较常规的操作&#xff0c;因为到手的影像可能是多种范围&#xff0c;需要根据自己需求进行裁剪&#xff0c;这里为大家介绍一下ArcGIS Pro中裁剪的方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的影像和行政区…

Java EE 多线程之 JUC

文章目录 1. Callable 接口2. ReentrantLock3. 信号量4. CountDownLatch JUC这里就是指&#xff08;java.util.concurrent&#xff09; concurrent 就是并发的意思 这个包里的内容&#xff0c;主要就是一些多线程相关的组件 1. Callable 接口 Callable 也是一种创建线程的方式…

Go 与 Rust:现代编程语言的深度对比

在快速发展的软件开发领域中&#xff0c;选择合适的编程语言对项目的成功至关重要。Go 和 Rust 是两种现代编程语言&#xff0c;它们都各自拥有一系列独特的特性和优势。本文旨在深入比较 Go 和 Rust&#xff0c;从不同的角度分析这两种语言&#xff0c;包括性能、语言特性、生…

你好!赫夫曼树【JAVA】

目录 1.简单介绍 2.术语 3.构建思路 4.创建节点类 5.创建赫夫曼树 6.前序遍历 7.小玩一把 1.简单介绍 赫夫曼树&#xff08;Huffman Tree&#xff09;又称最优二叉树&#xff0c;是一种带权路径长度最短的二叉树。它的构建主要用于数据压缩算法中&#xff0c;根据字…

【vue】jenkins打前端包时报错:第 8 行:cd: dist: 没有那个文件或目录

问题描述 jenkins打前端包时报错&#xff1a;第 8 行&#x1f4bf; dist: 没有那个文件或目录 Jenkins中 “Execute shell” 配置的脚本&#xff1a; echo $PATH node -v npm -v npm config set registry http://ued.edtsoft.com/ npm install npm run build:prod cd dist rm…

数据结构(七):树介绍及面试常考算法

一、树介绍 1、定义 树形结构是一种层级式的数据结构&#xff0c;由顶点&#xff08;节点&#xff09;和连接它们的边组成。 树类似于图&#xff0c;但区分树和图的重要特征是树中不存在环路。树有以下特点&#xff1a; &#xff08;1&#xff09;每个节点有零个或多个子节点…

牛客网BC100有序序列合并

思路&#xff1a; 运用归并排序&#xff1a; 假设给定我们两个都是升序的数组&#xff0c;要求我们要把这两个数组以升序的方式合并到一个数组中&#xff0c;则我们就可以在这两个数组中分别各拿取一个元素进行比较&#xff0c;将二者之间较小值先放在这个新数组中&#xff0c…

函数图形渐近线分析

文章目录 曲线的渐近线水平和垂直渐近线斜渐近线斜渐近线公式推导简便方法确定斜渐近线(一次多项式化方法) 例 曲线的渐近线 渐近线综合了极限和函数图形的知识,尤其是斜渐近线 水平和垂直渐近线 若点 M M M沿曲线 y f ( x ) yf(x) yf(x)无限远离原点时,它于某条直线 L L L之…

web应用开发技术的一些概念

一、Servlet 1.Servlet的工作过程&#xff1a; Servelt的工作流程示意图 &#xff08;1&#xff09;客户端发起一个Http请求到服务器&#xff0c;请求特定的资源或者是要执行特定的操作 &#xff08;2&#xff09;服务器在接收到请求后&#xff0c;根据请求相应的URL将请求分发…

2023.12.15 FineBI与kettle

1.结构化就是可以用schema描述的数据,就是结构化数据,能转为二维表格, 如CSV,Excel, 2.半结构化就是部分可以转换为二维表格,如JSON,XML 3.非结构化数据,就是完全无法用二维表格表示的数据,如Word文档,Mp4,图片,等文件. kettle的流程 新建转换-构建流图-配置组件-保存运行 使…

人工智能与星际旅程:技术前沿与未来展望

人工智能与星际旅程&#xff1a;技术前沿与未来展望 一、引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;在各个领域的应用越来越广泛。在星际旅程领域&#xff0c;AI也发挥着越来越重要的作用。本文将探讨人工智能与星际旅程的结合&#xff0c;以及…

微服务架构之争:Quarkus VS Spring Boot

在容器时代&#xff08;“Docker时代”&#xff09;&#xff0c;无论如何&#xff0c;Java仍然活着。Java在性能方面一直很有名&#xff0c;主要是因为代码和真实机器之间的抽象层&#xff0c;多平台的成本&#xff08;一次编写&#xff0c;随处运行——还记得吗&#xff1f;&a…