SpringBoot整合Flowable工作流-1(画流程定义)

1. 前言

由于内容比较多,一篇文章可能还介绍不完,接下来可能会分成几篇文章进行介绍。


相信很多人都听说过或者了解过工作流,也在生活中接触不少,比如OA系统的审批。
目前国内有很多工作流引擎,但是大多数都是集成第三方国外的引擎做二次开发的。

2. Flowable 简单介绍

Flowable 是一个用Java编写的轻量级业务流程引擎。Flowable 流程引擎允许您部署BPMN 2.0流程定义(用于定义流程的行业XML标准)、创建这些流程定义的流程实例、运行查询、访问活动或历史流程实例和相关数据。

Flowable 在将其添加到应用程序/服务/体系结构时非常灵活。您可以将引擎嵌入到您的应用程序或服务中,方法是包含 Flowable库,该库作为JAR提供。因为它是一个JAR,所以可以很容易地将它添加到任何Java环境中:javase;servlet容器,如Tomcat或Jetty、Spring;javaee服务器,如JBoss或WebSphere等。或者,您可以使用可流动的restapi通过HTTP进行通信。还有一些可流动的应用程序(Flowable Modeler、Flowable Admin、Flowable IDM 和 Flowable Task),它们提供了用于处理流程和任务的现成示例ui。

所有设置Flowable的方法都有一个共同点,那就是核心引擎,它可以看作是一个服务集合,公开api来管理和执行业务流程。【摘录于Flowable Getting Started】

3. 看一下效果

【流程定义管理】

【任务管理 - 待办任务】

【任务管理 - 已办任务】

【任务管理 - 范围任务】

【任务管理 - 我发起的】

【业务列表】

4. 创建流程定义(画流程图)

问:如何画流程图呢?用什么画呢?
答:Flowable 流程引擎允许部署bpmn2.0流程定义,说明bpmn2.0流程定义是一个比较通用的规范,因此也是有不少工具的,常用的开发工具,如 Eclpise、IDEA 这些都是可以画的,但是我是使用 Flowable 提供的 ui 工具画的,或者你也可以使用我搭建出来的在线工具画。

4.1 自己搭建流程设计器服务

如果你想自己搭建 flowable-ui 也是比较方便的,首先下载文件 Flowable 相关的资源,进入 https://flowable.com/open-source/downloads,然后点击 【Download Flowable v6.x.x】,下载下来是一个压缩包,解压压缩会看到如下目录结构

├─database                                   # 数据库文件
│  ├─create        
│  └─upgrade  
├─docs                                       # 文档
├─libs                                       # 相关的jar
└─wars
   ├─flowable-rest.war                       # rest 服务(基于 SpringBoot)
   ├─flowable-ui.war                         # 流程ui设计器(基于 SpringBoot)
   └─data

在目录 $/wars/flowable-ui.war 下,看到是一个war包,可以放到tomcat中也可以使用命令跑起来

java -jar flowable-ui.war

默认是8080端口,你可以修改端口,首次登录需要账号和密码。
账号:admin
密码:test

4.2 使用在线流程设计器服务

其实我也是基于 flowable-ui 搭建的,我部署到我的学生服务器上面了,并且提供了外网访问地址,如下

地址:http://flowable.ui.ihouyu.cn/flowable-ui/modeler/#/processes
账号:admin
密码:test

4.3 画第一个流程图

登录后,你可以【创建流程】也可以【导入流程】,如下图

点击对应的流程进入流程管理页面。

第一个流程图想实现的效果:

提交流程
----主管审批?
    ----主管拒绝,流程结束(失败)
    ----主管同意
        ----经理审批?
            ----经理拒绝,流程结束(失败)
            ----经理同意,流程结束(成功)

进入可视化编辑器后,需要重点了解一下的是:流程标识(启动流程的Key)名称(流程的名称)数据对象(存储流程的数据变量等)

全局数据对象的使用

后面可以通过代码 BpmnModel 对象获取到流程图里边的所有定义信息

添加开始事件

添加用户活动(用户审批)

添加网关

添加结束事件

设置【主管审批】的主键ID、分配用户等

1.主键ID:可以结合业务需求,业务可以根据不同步骤执行不同的业务操作
2.分配用户:这里为了方便,直接选择了固定值,这里的候选组是具体的业务系统的角色ID从而实现不同角色审批不同流程的效果

设置【网关】的流条件

连线条件的输入框是支持EL表达式,因此可以使用{} 【同意的条件】:这里填写了{executeType == 'YES'} 的意思是主管审批的时候传递一个 executeType 变量,并且 executeType 变量的值为 YES 的时候,则走到下一步(经理审批)

【拒绝的条件】:这里填写了 ${executeType == 'NO'} 的意思是主管审批的时候传递一个 executeType 变量,并且 executeType 变量的值为 NO 的时候,则结束流程。

最后下载下来之后是一个“请假流程1.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:flowable="http://flowable.org/bpmn" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
  <process id="Leave1" name="请假流程1" isExecutable="true">
    <documentation>Leave描述信息1</documentation>
    <dataObject id="businessDataViewUri" name="业务数据视图链接" itemSubjectRef="xsd:string">
      <extensionElements>
        <flowable:value>/workflow/leave-info</flowable:value>
      </extensionElements>
    </dataObject>
    <dataObject id="businessNotifyUri" name="业务通知链接" itemSubjectRef="xsd:string">
      <extensionElements>
        <flowable:value>/workflow/test/leave/workflow-notify</flowable:value>
      </extensionElements>
    </dataObject>
    <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
    <userTask id="zgsp1" name="主管审批" flowable:candidateGroups="847922232536731648" flowable:formFieldValidation="true"></userTask>
    <sequenceFlow id="sid-28954DF2-874B-43D5-9057-AD04F13D11BC" sourceRef="startEvent1" targetRef="zgsp1"></sequenceFlow>
    <exclusiveGateway id="sid-CFB93847-6029-435E-892E-7FC34AE2A425"></exclusiveGateway>
    <sequenceFlow id="sid-8C1A8676-53FC-4A62-920D-24F38C57B603" sourceRef="zgsp1" targetRef="sid-CFB93847-6029-435E-892E-7FC34AE2A425"></sequenceFlow>
    <userTask id="jlsp1" name="经理审批" flowable:candidateGroups="847922477412782081" flowable:formFieldValidation="true"></userTask>
    <endEvent id="sid-00609504-6F1A-48AE-AA66-058B01A367FB"></endEvent>
    <exclusiveGateway id="sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151"></exclusiveGateway>
    <sequenceFlow id="sid-3F6C0888-623F-42C2-8F06-397C83F44DCE" sourceRef="jlsp1" targetRef="sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151"></sequenceFlow>
    <endEvent id="sid-96443FBA-145F-43DE-AE91-D11B5A0115F2"></endEvent>
    <endEvent id="sid-8DE7ABDB-F814-41D5-B1EC-FE0628D7D810"></endEvent>
    <sequenceFlow id="sid-21A1CF4B-19B7-4DE1-A777-C2C4764A6D05" name="拒绝" sourceRef="sid-CFB93847-6029-435E-892E-7FC34AE2A425" targetRef="sid-00609504-6F1A-48AE-AA66-058B01A367FB">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType == 'NO'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-F7498CFB-1603-4E64-A788-92CBCBBEC794" name="拒绝" sourceRef="sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151" targetRef="sid-8DE7ABDB-F814-41D5-B1EC-FE0628D7D810">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType == 'NO'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-8866076B-0723-41A2-AACF-DDC7B06226D9" name="同意" sourceRef="sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151" targetRef="sid-96443FBA-145F-43DE-AE91-D11B5A0115F2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType == 'YES'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-27560005-7B06-4F2D-BD9A-7FE27C7410A0" name="同意" sourceRef="sid-CFB93847-6029-435E-892E-7FC34AE2A425" targetRef="jlsp1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType == 'YES'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_Leave1">
    <bpmndi:BPMNPlane bpmnElement="Leave1" id="BPMNPlane_Leave1">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="zgsp1" id="BPMNShape_zgsp1">
        <omgdc:Bounds height="80.0" width="100.0" x="210.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-CFB93847-6029-435E-892E-7FC34AE2A425" id="BPMNShape_sid-CFB93847-6029-435E-892E-7FC34AE2A425">
        <omgdc:Bounds height="40.0" width="40.0" x="390.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="jlsp1" id="BPMNShape_jlsp1">
        <omgdc:Bounds height="80.0" width="100.0" x="525.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-00609504-6F1A-48AE-AA66-058B01A367FB" id="BPMNShape_sid-00609504-6F1A-48AE-AA66-058B01A367FB">
        <omgdc:Bounds height="28.0" width="28.0" x="396.0" y="270.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151" id="BPMNShape_sid-E68077F0-E0AA-49DA-B0C2-BE8A0693E151">
        <omgdc:Bounds height="40.0" width="40.0" x="720.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-96443FBA-145F-43DE-AE91-D11B5A0115F2" id="BPMNShape_sid-96443FBA-145F-43DE-AE91-D11B5A0115F2">
        <omgdc:Bounds height="28.0" width="28.0" x="840.0" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-8DE7ABDB-F814-41D5-B1EC-FE0628D7D810" id="BPMNShape_sid-8DE7ABDB-F814-41D5-B1EC-FE0628D7D810">
        <omgdc:Bounds height="28.0" width="28.0" x="726.0" y="270.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-F7498CFB-1603-4E64-A788-92CBCBBEC794" id="BPMNEdge_sid-F7498CFB-1603-4E64-A788-92CBCBBEC794">
        <omgdi:waypoint x="740.0" y="197.9405984919887"></omgdi:waypoint>
        <omgdi:waypoint x="740.0" y="270.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-21A1CF4B-19B7-4DE1-A777-C2C4764A6D05" id="BPMNEdge_sid-21A1CF4B-19B7-4DE1-A777-C2C4764A6D05">
        <omgdi:waypoint x="410.0" y="197.9405984919887"></omgdi:waypoint>
        <omgdi:waypoint x="410.0" y="270.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-8866076B-0723-41A2-AACF-DDC7B06226D9" id="BPMNEdge_sid-8866076B-0723-41A2-AACF-DDC7B06226D9">
        <omgdi:waypoint x="759.9412576686476" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="840.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-27560005-7B06-4F2D-BD9A-7FE27C7410A0" id="BPMNEdge_sid-27560005-7B06-4F2D-BD9A-7FE27C7410A0">
        <omgdi:waypoint x="429.94395820712947" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="524.9999999999847" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-28954DF2-874B-43D5-9057-AD04F13D11BC" id="BPMNEdge_sid-28954DF2-874B-43D5-9057-AD04F13D11BC">
        <omgdi:waypoint x="129.94999913076796" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="209.99999999998067" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-8C1A8676-53FC-4A62-920D-24F38C57B603" id="BPMNEdge_sid-8C1A8676-53FC-4A62-920D-24F38C57B603">
        <omgdi:waypoint x="309.9499999999581" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="390.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-3F6C0888-623F-42C2-8F06-397C83F44DCE" id="BPMNEdge_sid-3F6C0888-623F-42C2-8F06-397C83F44DCE">
        <omgdi:waypoint x="624.9499999998898" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="720.0" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

到这里,就画好了第一个简单的流程图了。
下篇博客将介绍根据流程图 基于 SpringBoot 整合 Flowable 的代码实现。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容