camunda流程引擎简明教程

前言

公司项目中使用到了camunda引擎,这个技术框架在国内的文章还是比较少,于是自己在使用中先做一部分总结

首先上官网doc地址,目前已经更新到了7.13版本 https://docs.camunda.org/manual/7.13/
如果学习使用可以搭配camunda modeler这个官方的应用,用来可视化的打开和编辑流程模型文件

一般来讲,流程引擎可以使用在像流程审批,请假,以及一些需要过程性的任务上,他可以提供一种可复用,简便以及易更改的特点,所以在有上述业务需求的场景下,可以考虑使用camunda

本文选用bpmn模型

概念

camunda的起源是来自于activity,在activity开发中团队内出现了分歧,所以一部分人转移到一个新的项目中,就是camunda

在camunda中,我们首先需要定义一个流程模型,有开始节点和结束节点,中间可以增加用户任务(userTask),门(gateway)和监听器(listener)等等
这个流程模型就叫做processDefinition(流程模型定义)

我们可以调用api,开始一段新的流程实例(processInstance),流程实例会经过流程模型上的每一个节点,生成对应的任务,通过自动或用户手动完成任务,使得流程实例流转到下一个节点

流程实例和用户任务都可以携带变量,这些变量可以区分为全局变量和本地变量以供我们在适当的时候读取,例如遇到监听器或者门,就可以通过变量决定做些事情或进入不同的分支

整个过程有点类似java中的线程,模型定义中的节点就是一个个的类或者一个个方法,开始节点是main方法,运行main方法开启线程,线程会经过不同的方法,最终完成调用

使用camunda modeler可以规划模型定义,像下图中

整合springboot

camunda可以整合到springboot中,他提供了一个springboot-stater的专用版本

部署流程模型

在项目中,我们可以在resource目录下定义一个processes文件夹,里面可以放camunda modeler生成的模型文件,在应用启动的时候,会将该模型加载到数据库中
当然除了这种静态的加载方式,我们也可以调用camunda-engine提供的api,在运行时按照要求生成对应的模型并部署
这种方式可以运用在业务中实时的编辑流程,编辑完后保存,后端去解析然后生成流程模型

开始编码

在程序中,我们可以使用@resouce注解来使得spring注入camunda相关的api对象,例如RuntimeService, RepositoryService, TaskService或者HistoryService

1
2
3
4
RuntimeService    用来启动,停止,编辑运行中的实例变量
RepositoryService 用来查找或操作部署的流程模型等
TaskService 专门操作task
HistoryService 操作所有历史的内容,例如已经完成的流程实例或完成的task

需要注意的是一个流程实例或者任务,在运行中会同时出现在runtimehistory两个表中,而结束后则会从runtime表中移除,所以我通常在查询时只查询history

启动流程

可以使用RuntimeService#startprocessInstanceById()或者其他的start方法来开启一段流程

camunda中的任务

task的类型

task有很多类型,比如脚本任务,用户任务等等,用户任务是一种需要手动完成的任务才能使得流程继续流转的任务,也是比较常用的任务,我们可以来说说他
用户任务可以分为单一任务或批量任务,而批量任务又可以分为串行任务和并行任务
一个任务的所有者叫做assignee,在单一任务中,只要制定一个具体的值到assignee中即可,流程流转到这里时会生成一个task的实例
而批量任务则需要指定一个用户集合,放在collection中,使用element variable来标记一个用户,在assignee处使用element variable的变量,这有点像for循环的写法
在批量任务中,camunda会生成多个任务实例,串行属性的多任务,会按照collection中的用户顺序,先生成一个,完成之后生成下一个,并行属性的多任务,会同时生成所有collection中的用户任务实例
串行一般用在比如请假中的领导审批,并行一般用在领导通过后的抄送中

task中的监听器

在task中可以使用listener,可以完成一些复杂的业务逻辑,比如某些情况下的任务自动通过,或者用户完成任务后发送业务通知消息等等
task的listener可以在模型定义中写死listener的class全路径

也可以在项目中使用注解+表达式在运行时attach到对应的任务实例上,当然我比较推荐后者,这样会比较灵活,不会因为listener的位置变了而重新部署模型

总结

camunda的文档写的还是相对完善,推荐多去阅读,另外camunda的官方社区也是相对活跃,一般问题都可以在上面搜的到