activities怎么读 Activiti7 入门篇

1.  工作流
简单地来讲,工作流就是在计算机的协助下实现流程的自动化控制 。目前,笔者熟知的主流的框架有:Camunda 、Flowable 、Activiti 、jBPM、还有我们国产的盘古BPM、云程 。其中,Camunda 、Flowable 都有商业版(企业版)和非商业版(社区开源版) 。
技术产品各有千秋,Flowable专注于流程引擎,Activiti现在专注于Cloud 。笔者最推荐Camunda,盘古BPM还没用过看起来应该也挺好用的 。

activities怎么读 Activiti7 入门篇

文章插图
关于Camunda补充几篇文章
  • Camunda开源版与商业版的差异 
  • idea开发工作流使用camunda-model进行activiti7的开发
  • 基于camunda如何实现会签:camunda会签流程配置与原理解析
2.  流程设计器
笔者亲测,IntelliJ IDEA 2021.1 (Ultimate Edition)  不支持 actiBPM插件 。
强烈推荐用 camunda-modeler ,或者用 bpmn-js
首先,下载Camunda
https://camunda.com/download/
activities怎么读 Activiti7 入门篇

文章插图
解压以后,直接双击.exe文件运行
也可以在IDEA中把它作为外部工具用
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
笔者更习惯直接双击.exe打开
Activiti为Eclipse开发了一个BPM插件“Activiti Eclipse Designer”
https://www.activiti.org/userguide/index.html#activitiDesigner
activities怎么读 Activiti7 入门篇

文章插图
为了使用Activiti Designer,笔者又下载了Eclipse IDE,专门为了Activiti开发
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
3.  Activiti7 快速开始
工作流的作用是实现流程的自动化控制 。使用Activiti这种工作流框架大致都分为以下几个步骤:
  1. 流程定义
  2. 部署流程定义
  3. 启动流程实例
  4. 查询代表任务
  5. 完成任务
  6. 结束流程
术语补充:
  • BPM :业务流程管理
  • BPMN :业务流程模型和符号
首先,来引入依赖
1 <dependency>2<groupId>org.activiti</groupId>3<artifactId>activiti-spring-boot-starter</artifactId>4<version>7.1.0.M6</version>5 </dependency>学习Activiti主要是学习这些Service的使用
activities怎么读 Activiti7 入门篇

文章插图
 
3.1.  创建ProcessEngine
1 package com.cjs.example.activiti; 23 import org.activiti.engine.ProcessEngine; 4 import org.activiti.engine.ProcessEngineConfiguration; 5 import org.activiti.engine.ProcessEngines; 6 import org.junit.jupiter.api.Test; 78 /** 9* @Author ChengJianSheng10* @Date 2021/7/611*/12 public class ProcessEngineTests {13 14@Test15public void testProcessEngine1() {16ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();17System.out.println(processEngine);18}19 20@Test21public void testProcessEngine2() {22ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");23ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();24System.out.println(processEngine);25}26 27 }ProcessEngineConfiguration是用来创建ProcessEngine,默认情况下,会读取classpath下的activiti.cfg.xml文件,当然也可以不叫这个名字
这里,由于还没有与Spring Boot整合,也不是一个Web环境,所以,姑且先建一个这样的文件吧,真正开发的时候肯定不是这样做的
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 56<bean id="processEngineConfiguration" name="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> 7<property name="jdbcDriver" value="https://tazarkount.com/read/com.mysql.jdbc.Driver"/> 8<property name="jdbcUrl" value="https://tazarkount.com/read/jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8"/> 9<property name="jdbcUsername" value="https://tazarkount.com/read/root"/>10<property name="jdbcPassword" value="https://tazarkount.com/read/123456"/>11<property name="databaseSchemaUpdate" value="https://tazarkount.com/read/true"/>12</bean>13 </beans>只要ProcessEngine被成功创建,就会生成25张表
activities怎么读 Activiti7 入门篇

文章插图
这里我们可以看出,Activiti最本质最核心的东西就是将流程定义转换成表记录,表面上看好像是一个图片,其实它是一个xml文件,通过解析xml文件,进而将其转成表数据,后续从表中读数据就可以了 。
3.2.  流程定义
用 Camunda Modeler  或者 Activiti Eclipse Designer 画好流程图
activities怎么读 Activiti7 入门篇

文章插图
1 <?xml version="1.0" encoding="UTF-8"?> 2 <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4xmlns:xsd="http://www.w3.org/2001/XMLSchema" 5xmlns:activiti="http://activiti.org/bpmn" 6xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 7xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" 8xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" 9typeLanguage="http://www.w3.org/2001/XMLSchema"10expressionLanguage="http://www.w3.org/1999/XPath"11targetNamespace="http://www.activiti.org/test">12 13<process id="holiday" name="holiday" isExecutable="true">14<startEvent id="startevent1" name="Start"></startEvent>15<userTask id="usertask1" name="填写请假单" activiti:assignee="${assignee1}"></userTask>16<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>17<userTask id="usertask2" name="部门经理审批" activiti:assignee="${assignee2}"></userTask>18<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>19<userTask id="usertask3" name="人事审批" activiti:candidateUsers="tom,jerry"></userTask>20<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>21<endEvent id="endevent1" name="End"></endEvent>22<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>23</process>24 25<bpmndi:BPMNDiagram id="BPMNDiagram_holiday">26<bpmndi:BPMNPlane bpmnElement="holiday" id="BPMNPlane_holiday">27<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">28<omgdc:Bounds height="35.0" width="35.0" x="130.0" y="220.0"></omgdc:Bounds>29</bpmndi:BPMNShape>30<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">31<omgdc:Bounds height="55.0" width="105.0" x="210.0" y="210.0"></omgdc:Bounds>32</bpmndi:BPMNShape>33<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">34<omgdc:Bounds height="55.0" width="105.0" x="360.0" y="210.0"></omgdc:Bounds>35</bpmndi:BPMNShape>36<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">37<omgdc:Bounds height="55.0" width="105.0" x="510.0" y="210.0"></omgdc:Bounds>38</bpmndi:BPMNShape>39<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">40<omgdc:Bounds height="35.0" width="35.0" x="660.0" y="220.0"></omgdc:Bounds>41</bpmndi:BPMNShape>42<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">43<omgdi:waypoint x="165.0" y="237.0"></omgdi:waypoint>44<omgdi:waypoint x="210.0" y="237.0"></omgdi:waypoint>45</bpmndi:BPMNEdge>46<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">47<omgdi:waypoint x="315.0" y="237.0"></omgdi:waypoint>48<omgdi:waypoint x="360.0" y="237.0"></omgdi:waypoint>49</bpmndi:BPMNEdge>50<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">51<omgdi:waypoint x="465.0" y="237.0"></omgdi:waypoint>52<omgdi:waypoint x="510.0" y="237.0"></omgdi:waypoint>53</bpmndi:BPMNEdge>54<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">55<omgdi:waypoint x="615.0" y="237.0"></omgdi:waypoint>56<omgdi:waypoint x="660.0" y="237.0"></omgdi:waypoint>57</bpmndi:BPMNEdge>58</bpmndi:BPMNPlane>59</bpmndi:BPMNDiagram>60 61 </definitions>
activities怎么读 Activiti7 入门篇

文章插图
1 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 23 RepositoryService repositoryService = processEngine.getRepositoryService(); 45 Deployment deployment = repositoryService.createDeployment() 6.addClasspathResource("diagram/holiday.bpmn") 7.addClasspathResource("diagram/holiday.png") 8.name("请假流程") 9.key("holiday")10.deploy();11 12 13 //Deployment deployment = repositoryService.createDeployment()14 //.addZipInputStream()15 //.name()16 //.key()17 //.deploy();18 19 System.out.println(deployment.getId());也可以把这两个文件放在一起打包程一个zip压缩包
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
可以看到,act_re_procdef表中关联了act_re_deployment的ID,act_ge_bytearray表中也关联了act_re_deployment的ID
processDefinitionId是holiday:1:4
deploymentId是1
1 RepositoryService repositoryService = processEngine.getRepositoryService(); 23 //查询流程部署 4 Deployment deployment = repositoryService.createDeploymentQuery().deploymentKey("holiday").singleResult(); 5 //查询流程定义 6 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); 7 //流程定义是否被挂起/暂停 8 boolean suspended = processDefinition.isSuspended(); 9 //删除部署10 repositoryService.deleteDeployment(deployment.getId());11 //激活流程定义12 repositoryService.activateProcessDefinitionById(processDefinition.getId());13 //挂起/暂停流程定义14 repositoryService.suspendProcessDefinitionById(processDefinition.getId());15 //查看流程图图片16 InputStream is = repositoryService.getResourceAsStream(deployment.getId(), processDefinition.getDiagramResourceName());3.3.  流程实例
activities怎么读 Activiti7 入门篇

文章插图
1 RuntimeService runtimeService = processEngine.getRuntimeService(); 23 Map<String, Object> variables = new HashMap<>(); 4 variables.put("assignee1", "zhangsan"); 5 variables.put("assignee2", "lisi"); 78 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", variables); 9 10 System.out.println(processInstance.getProcessInstanceId());11 System.out.println(processInstance.getProcessDefinitionId());
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
3.5.  任务
1 TaskService taskService = processEngine.getTaskService();2 //查询待办任务3 List<Task> taskList = taskService.createTaskQuery().taskAssignee("zhangsan").list();4 5 for (Task task : taskList) {6//完成任务7taskService.complete(task.getId());8 }现在,已经完成了zhangsan和lisi的任务,流程已经走到人事审批了,看表
activities怎么读 Activiti7 入门篇

文章插图
 
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
接下来,查询tom和jerry的任务时,就不能用taskAssignee("tom")这样了,因为人事审批这个节点设置的是两个候选者,他们都可以看到任务,但是最终只能由一个人去完成
activities怎么读 Activiti7 入门篇

文章插图
首先,需要声明任务由谁负责,然后再完成,不然任务不会分配给任何人
1 TaskService taskService = processEngine.getTaskService(); 23 //查询待办任务 4 Task task = taskService.createTaskQuery() 5.processDefinitionKey("holiday") 6.taskCandidateUser("tom") 7.singleResult(); 89 //声明任务的责任人是谁10 taskService.claim(task.getId(), "tom");11 12 //完成任务13 taskService.complete(task.getId());在tom拾取了这个任务以后,当前任务就分配给了tom
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
假设,拾取任务以后不想办理了,可以选择将自己当前的任务指派给其他人办理,或者再还回去
当我们把任务指派给jack以后
1 /** 2* 指派 3*/ 45 //指派的第一种方式 6 taskService.setAssignee(task.getId(), "jack"); 78 //指派的第二种方式 9 taskService.deleteCandidateUser(task.getId(), "tom");10 taskService.addCandidateUser(task.getId(), "jack");
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
还可以将任务委派给他人做
委派:是将任务节点分给其他人处理,等其他人处理好之后,委派任务会自动回到委派人的任务中
1 //将任务进行委派2 taskService.delegateTask(task.getId(), "rose");3 //被委派人办理任务后,委派人标记任务已完成4 taskService.resolveTask(task.getId());将任务重新放回去
1 /**2* 将任务重新放回去3*/4 //第一种写法5 taskService.unclaim(task.getId());6 //第二种写法7 taskService.setAssignee(task.getId(), null);完整代码片段如下:
1 //查询待办任务 2 Task task = taskService.createTaskQuery() 3.processDefinitionKey("holiday") 4 //.taskCandidateUser("tom") 5.taskAssignee("jack") 6.singleResult(); 78 //拾取任务 9 taskService.claim(task.getId(), "tom");10 11 //指派12 taskService.setAssignee(task.getId(), "jack");13 14 taskService.deleteCandidateUser(task.getId(), "tom");15 taskService.addCandidateUser(task.getId(), "jack");16 17 //重新放回去18 taskService.setAssignee(task.getId(), null);19 taskService.unclaim(task.getId());20 21 //完成任务22 taskService.complete(task.getId());人事审批后,整个流程就结束了 
activities怎么读 Activiti7 入门篇

文章插图
一个流程实例走完以后,后续只能通过历史记录去查询它了
1 HistoryService historyService = processEngine.getHistoryService();2 //历史查询3 List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()4.processInstanceId("7501").orderByHistoricActivityInstanceStartTime().asc().list();5 for (HistoricActivityInstance historicActivityInstance : list) {6System.out.println(historicActivityInstance.getActivityName() + ":" + historicActivityInstance.getAssignee());7 }3.6.  网关
前面的请假流程比较简单(PS:故意简单设置的),接下来再看一下稍微复杂一点的报销流程(PS:也是故意复杂设置的)
activities怎么读 Activiti7 入门篇

文章插图
1 <?xml version="1.0" encoding="UTF-8"?>2 <definitions3xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"4xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"5xmlns:xsd="http://www.w3.org/2001/XMLSchema"6xmlns:activiti="http://activiti.org/bpmn"7xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"8xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"9xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" 10typeLanguage="http://www.w3.org/2001/XMLSchema" 11expressionLanguage="http://www.w3.org/1999/XPath" 12targetNamespace="http://www.activiti.org/test"> 1314<process id="expense" name="expense" isExecutable="true"> 15<documentation>报销流程</documentation> 16<startEvent id="startevent1" name="Start"></startEvent> 17<userTask id="usertask1" name="填写报销单" activiti:assignee="${expense.username}"></userTask> 18<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> 19<userTask id="usertask2" name="部门经理审批" activiti:assignee="${deptManager}"></userTask> 20<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow> 21<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> 22<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow> 23<userTask id="usertask3" name="人事审批" activiti:assignee="${cho}"></userTask> 24<sequenceFlow id="flow6" sourceRef="exclusivegateway2" targetRef="usertask3"> 25<conditionExpression xsi:type="tFormalExpression"><![CDATA[${expense.amount <= 500}]]></conditionExpression> 26</sequenceFlow> 27<userTask id="usertask4" name="总经理审批" activiti:assignee="${ceo}"></userTask> 28<sequenceFlow id="flow8" sourceRef="usertask4" targetRef="usertask3"></sequenceFlow> 29<sequenceFlow id="flow10" sourceRef="exclusivegateway2" targetRef="usertask4"> 30<conditionExpression xsi:type="tFormalExpression"><![CDATA[${expense.amount > 500}]]></conditionExpression> 31</sequenceFlow> 32<userTask id="usertask5" name="打印申请单" activiti:assignee="zhangsan"></userTask> 33<userTask id="usertask6" name="粘贴发票" activiti:assignee="lisi"></userTask> 34<parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway> 35<sequenceFlow id="flow11" sourceRef="usertask3" targetRef="parallelgateway1"></sequenceFlow> 36<sequenceFlow id="flow12" sourceRef="parallelgateway1" targetRef="usertask5"></sequenceFlow> 37<sequenceFlow id="flow13" sourceRef="parallelgateway1" targetRef="usertask6"></sequenceFlow> 38<parallelGateway id="parallelgateway2" name="Parallel Gateway"></parallelGateway> 39<sequenceFlow id="flow15" sourceRef="usertask5" targetRef="parallelgateway2"></sequenceFlow> 40<sequenceFlow id="flow16" sourceRef="usertask6" targetRef="parallelgateway2"></sequenceFlow> 41<userTask id="usertask7" name="财务打款" activiti:assignee="${cfo}"></userTask> 42<sequenceFlow id="flow17" sourceRef="parallelgateway2" targetRef="usertask7"></sequenceFlow> 43<endEvent id="endevent1" name="End"></endEvent> 44<sequenceFlow id="flow18" sourceRef="usertask7" targetRef="endevent1"></sequenceFlow> 45</process> 46<bpmndi:BPMNDiagram id="BPMNDiagram_expense"> 47<bpmndi:BPMNPlane bpmnElement="expense" id="BPMNPlane_expense"> 48<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> 49<omgdc:Bounds height="35.0" width="35.0" x="70.0" y="255.0"></omgdc:Bounds> 50</bpmndi:BPMNShape> 51<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> 52<omgdc:Bounds height="55.0" width="105.0" x="140.0" y="245.0"></omgdc:Bounds> 53</bpmndi:BPMNShape> 54<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> 55<omgdc:Bounds height="55.0" width="105.0" x="280.0" y="245.0"></omgdc:Bounds> 56</bpmndi:BPMNShape> 57<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"> 58<omgdc:Bounds height="40.0" width="40.0" x="430.0" y="252.0"></omgdc:Bounds> 59</bpmndi:BPMNShape> 60<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"> 61<omgdc:Bounds height="55.0" width="105.0" x="520.0" y="245.0"></omgdc:Bounds> 62</bpmndi:BPMNShape> 63<bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4"> 64<omgdc:Bounds height="55.0" width="105.0" x="520.0" y="130.0"></omgdc:Bounds> 65</bpmndi:BPMNShape> 66<bpmndi:BPMNShape bpmnElement="usertask5" id="BPMNShape_usertask5"> 67<omgdc:Bounds height="55.0" width="105.0" x="750.0" y="159.0"></omgdc:Bounds> 68</bpmndi:BPMNShape> 69<bpmndi:BPMNShape bpmnElement="usertask6" id="BPMNShape_usertask6"> 70<omgdc:Bounds height="55.0" width="105.0" x="750.0" y="320.0"></omgdc:Bounds> 71</bpmndi:BPMNShape> 72<bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1"> 73<omgdc:Bounds height="40.0" width="40.0" x="680.0" y="252.0"></omgdc:Bounds> 74</bpmndi:BPMNShape> 75<bpmndi:BPMNShape bpmnElement="parallelgateway2" id="BPMNShape_parallelgateway2"> 76<omgdc:Bounds height="40.0" width="40.0" x="880.0" y="252.0"></omgdc:Bounds> 77</bpmndi:BPMNShape> 78<bpmndi:BPMNShape bpmnElement="usertask7" id="BPMNShape_usertask7"> 79<omgdc:Bounds height="55.0" width="105.0" x="961.0" y="245.0"></omgdc:Bounds> 80</bpmndi:BPMNShape> 81<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> 82<omgdc:Bounds height="35.0" width="35.0" x="1100.0" y="255.0"></omgdc:Bounds> 83</bpmndi:BPMNShape> 84<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> 85<omgdi:waypoint x="105.0" y="272.0"></omgdi:waypoint> 86<omgdi:waypoint x="140.0" y="272.0"></omgdi:waypoint> 87</bpmndi:BPMNEdge> 88<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> 89<omgdi:waypoint x="245.0" y="272.0"></omgdi:waypoint> 90<omgdi:waypoint x="280.0" y="272.0"></omgdi:waypoint> 91</bpmndi:BPMNEdge> 92<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> 93<omgdi:waypoint x="385.0" y="272.0"></omgdi:waypoint> 94<omgdi:waypoint x="430.0" y="272.0"></omgdi:waypoint> 95</bpmndi:BPMNEdge> 96<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> 97<omgdi:waypoint x="470.0" y="272.0"></omgdi:waypoint> 98<omgdi:waypoint x="520.0" y="272.0"></omgdi:waypoint> 99</bpmndi:BPMNEdge>100<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">101<omgdi:waypoint x="572.0" y="185.0"></omgdi:waypoint>102<omgdi:waypoint x="572.0" y="245.0"></omgdi:waypoint>103</bpmndi:BPMNEdge>104<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">105<omgdi:waypoint x="450.0" y="252.0"></omgdi:waypoint>106<omgdi:waypoint x="450.0" y="157.0"></omgdi:waypoint>107<omgdi:waypoint x="520.0" y="157.0"></omgdi:waypoint>108</bpmndi:BPMNEdge>109<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">110<omgdi:waypoint x="625.0" y="272.0"></omgdi:waypoint>111<omgdi:waypoint x="680.0" y="272.0"></omgdi:waypoint>112</bpmndi:BPMNEdge>113<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">114<omgdi:waypoint x="700.0" y="252.0"></omgdi:waypoint>115<omgdi:waypoint x="700.0" y="186.0"></omgdi:waypoint>116<omgdi:waypoint x="750.0" y="186.0"></omgdi:waypoint>117</bpmndi:BPMNEdge>118<bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">119<omgdi:waypoint x="700.0" y="292.0"></omgdi:waypoint>120<omgdi:waypoint x="700.0" y="347.0"></omgdi:waypoint>121<omgdi:waypoint x="750.0" y="347.0"></omgdi:waypoint>122</bpmndi:BPMNEdge>123<bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">124<omgdi:waypoint x="855.0" y="186.0"></omgdi:waypoint>125<omgdi:waypoint x="900.0" y="186.0"></omgdi:waypoint>126<omgdi:waypoint x="900.0" y="252.0"></omgdi:waypoint>127</bpmndi:BPMNEdge>128<bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">129<omgdi:waypoint x="855.0" y="347.0"></omgdi:waypoint>130<omgdi:waypoint x="900.0" y="347.0"></omgdi:waypoint>131<omgdi:waypoint x="900.0" y="292.0"></omgdi:waypoint>132</bpmndi:BPMNEdge>133<bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">134<omgdi:waypoint x="920.0" y="272.0"></omgdi:waypoint>135<omgdi:waypoint x="961.0" y="272.0"></omgdi:waypoint>136</bpmndi:BPMNEdge>137<bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">138<omgdi:waypoint x="1066.0" y="272.0"></omgdi:waypoint>139<omgdi:waypoint x="1100.0" y="272.0"></omgdi:waypoint>140</bpmndi:BPMNEdge>141</bpmndi:BPMNPlane>142</bpmndi:BPMNDiagram>143 </definitions>引入了排他网关(Exclusive Gateway)和并行网关(Parallel Gateway)
1 @Data2 public class Expense implements Serializable {3//申请人4private String username;5//报销金额6private Integer amount;7 }启动流程实例
1 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 23 RepositoryService repositoryService = processEngine.getRepositoryService(); 4 RuntimeService runtimeService = processEngine.getRuntimeService(); 5 TaskService taskService = processEngine.getTaskService(); 67 //部署流程定义 8 Deployment deployment = repositoryService.createDeployment() 9.addClasspathResource("diagram/expense.bpmn")10.addClasspathResource("diagram/expense.png")11.name("报销流程")12.key("expense")13.deploy();14 15 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()16.deploymentId(deployment.getId())17.singleResult();18 System.out.println(processDefinition.getId());19 20 Expense expense = new Expense();21 expense.setUsername("chengcheng");22 expense.setAmount(520);23 24 Map<String, Object> variables = new HashMap<>();25 variables.put("expense", expense);26 variables.put("deptManager", "tom");27 variables.put("ceo", "jerry");28 variables.put("cho", "rose");29 variables.put("cfo", "jack");30 31 //启动流程实例32 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("expense", variables);33 System.out.println(processInstance.getId());34 35 //查询cheng的待办任务36 Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee("chengcheng").singleResult();37 if (null != task) {38taskService.complete(task.getId());39 }40 41 //完成tom的待办任务42 task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();43 String assignee = task.getAssignee();44 Assertions.assertEquals("tom", assignee);45 taskService.complete(task.getId());46 47 //判断当前任务走到总经理审批48 task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();49 assignee = task.getAssignee();50 Assertions.assertEquals("jerry", assignee);51 taskService.complete(task.getId());52 53 //完成rose的任务54 task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee("rose").singleResult();55 if (null != task) {56taskService.complete(task.getId());57 }58 59 //断言当前有2个激活的任务60 List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();61 taskList.forEach(x->{62System.out.println(x.getName() + " : " + x.getAssignee());63 });64 Assertions.assertEquals(2, taskList.size());
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
当我们完成了zhangsan和lisi的任务以后
activities怎么读 Activiti7 入门篇

文章插图
 
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
接下来,演示包含网关(Inclusive Gateway) 
activities怎么读 Activiti7 入门篇

文章插图
1 <?xml version="1.0" encoding="UTF-8"?>2 <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"4xmlns:xsd="http://www.w3.org/2001/XMLSchema"5xmlns:activiti="http://activiti.org/bpmn"6xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"7xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"8xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"9typeLanguage="http://www.w3.org/2001/XMLSchema" 10expressionLanguage="http://www.w3.org/1999/XPath" 11targetNamespace="http://www.activiti.org/test"> 1213<process id="HealthExamination" name="HealthExamination" isExecutable="true"> 14<startEvent id="startevent1" name="Start"></startEvent> 15<userTask id="usertask1" name="填写体检申请" activiti:assignee="${username}"></userTask> 16<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> 17<inclusiveGateway id="inclusivegateway1" name="Inclusive Gateway"></inclusiveGateway> 18<userTask id="usertask2" name="常规体检" activiti:assignee="${username}"></userTask> 19<userTask id="usertask3" name="癌症筛查" activiti:assignee="${username}"></userTask> 20<userTask id="usertask4" name="乙肝检查" activiti:assignee="${username}"></userTask> 21<sequenceFlow id="flow2" sourceRef="inclusivegateway1" 22targetRef="usertask2"> 23<conditionExpression xsi:type="tFormalExpression"><![CDATA[${userType == 1 || userType ==2}]]></conditionExpression> 24</sequenceFlow> 25<sequenceFlow id="flow4" sourceRef="inclusivegateway1" 26targetRef="usertask3"> 27<conditionExpression xsi:type="tFormalExpression"><![CDATA[${userType == 2}]]></conditionExpression> 28</sequenceFlow> 29<sequenceFlow id="flow5" sourceRef="inclusivegateway1" 30targetRef="usertask4"> 31<conditionExpression xsi:type="tFormalExpression"><![CDATA[${userType == 1 || userType ==2}]]></conditionExpression> 32</sequenceFlow> 33<sequenceFlow id="flow6" sourceRef="usertask1" targetRef="inclusivegateway1"></sequenceFlow> 34<inclusiveGateway id="inclusivegateway2" name="Inclusive Gateway"></inclusiveGateway> 35<sequenceFlow id="flow8" sourceRef="usertask4" targetRef="inclusivegateway2"></sequenceFlow> 36<sequenceFlow id="flow9" sourceRef="usertask2" targetRef="inclusivegateway2"></sequenceFlow> 37<sequenceFlow id="flow10" sourceRef="usertask3" targetRef="inclusivegateway2"></sequenceFlow> 38<userTask id="usertask5" name="吃早餐" activiti:assignee="${username}"></userTask> 39<endEvent id="endevent1" name="End"></endEvent> 40<sequenceFlow id="flow11" sourceRef="usertask5" targetRef="endevent1"></sequenceFlow> 41<sequenceFlow id="flow12" sourceRef="inclusivegateway2" targetRef="usertask5"></sequenceFlow> 42</process> 4344<bpmndi:BPMNDiagram id="BPMNDiagram_HealthExamination"> 45<bpmndi:BPMNPlane bpmnElement="HealthExamination" id="BPMNPlane_HealthExamination"> 46<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> 47<omgdc:Bounds height="35.0" width="35.0" x="100.0" y="254.0"></omgdc:Bounds> 48</bpmndi:BPMNShape> 49<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> 50<omgdc:Bounds height="55.0" width="105.0" x="180.0" y="244.0"></omgdc:Bounds> 51</bpmndi:BPMNShape> 52<bpmndi:BPMNShape bpmnElement="inclusivegateway1" id="BPMNShape_inclusivegateway1"> 53<omgdc:Bounds height="40.0" width="40.0" x="370.0" y="251.0"></omgdc:Bounds> 54</bpmndi:BPMNShape> 55<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> 56<omgdc:Bounds height="55.0" width="105.0" x="490.0" y="150.0"></omgdc:Bounds> 57</bpmndi:BPMNShape> 58<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"> 59<omgdc:Bounds height="55.0" width="105.0" x="490.0" y="340.0"></omgdc:Bounds> 60</bpmndi:BPMNShape> 61<bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4"> 62<omgdc:Bounds height="55.0" width="105.0" x="490.0" y="244.0"></omgdc:Bounds> 63</bpmndi:BPMNShape> 64<bpmndi:BPMNShape bpmnElement="inclusivegateway2" id="BPMNShape_inclusivegateway2"> 65<omgdc:Bounds height="40.0" width="40.0" x="690.0" y="251.0"></omgdc:Bounds> 66</bpmndi:BPMNShape> 67<bpmndi:BPMNShape bpmnElement="usertask5" id="BPMNShape_usertask5"> 68<omgdc:Bounds height="55.0" width="105.0" x="800.0" y="244.0"></omgdc:Bounds> 69</bpmndi:BPMNShape> 70<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> 71<omgdc:Bounds height="35.0" width="35.0" x="950.0" y="254.0"></omgdc:Bounds> 72</bpmndi:BPMNShape> 73<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> 74<omgdi:waypoint x="135.0" y="271.0"></omgdi:waypoint> 75<omgdi:waypoint x="180.0" y="271.0"></omgdi:waypoint> 76</bpmndi:BPMNEdge> 77<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> 78<omgdi:waypoint x="390.0" y="251.0"></omgdi:waypoint> 79<omgdi:waypoint x="390.0" y="177.0"></omgdi:waypoint> 80<omgdi:waypoint x="490.0" y="177.0"></omgdi:waypoint> 81</bpmndi:BPMNEdge> 82<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> 83<omgdi:waypoint x="390.0" y="291.0"></omgdi:waypoint> 84<omgdi:waypoint x="390.0" y="367.0"></omgdi:waypoint> 85<omgdi:waypoint x="490.0" y="367.0"></omgdi:waypoint> 86</bpmndi:BPMNEdge> 87<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"> 88<omgdi:waypoint x="410.0" y="271.0"></omgdi:waypoint> 89<omgdi:waypoint x="490.0" y="271.0"></omgdi:waypoint> 90</bpmndi:BPMNEdge> 91<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> 92<omgdi:waypoint x="285.0" y="271.0"></omgdi:waypoint> 93<omgdi:waypoint x="370.0" y="271.0"></omgdi:waypoint> 94</bpmndi:BPMNEdge> 95<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8"> 96<omgdi:waypoint x="595.0" y="271.0"></omgdi:waypoint> 97<omgdi:waypoint x="690.0" y="271.0"></omgdi:waypoint> 98</bpmndi:BPMNEdge> 99<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">100<omgdi:waypoint x="595.0" y="177.0"></omgdi:waypoint>101<omgdi:waypoint x="710.0" y="177.0"></omgdi:waypoint>102<omgdi:waypoint x="710.0" y="251.0"></omgdi:waypoint>103</bpmndi:BPMNEdge>104<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">105<omgdi:waypoint x="595.0" y="367.0"></omgdi:waypoint>106<omgdi:waypoint x="710.0" y="367.0"></omgdi:waypoint>107<omgdi:waypoint x="710.0" y="291.0"></omgdi:waypoint>108</bpmndi:BPMNEdge>109<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">110<omgdi:waypoint x="905.0" y="271.0"></omgdi:waypoint>111<omgdi:waypoint x="950.0" y="271.0"></omgdi:waypoint>112</bpmndi:BPMNEdge>113<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">114<omgdi:waypoint x="730.0" y="271.0"></omgdi:waypoint>115<omgdi:waypoint x="800.0" y="271.0"></omgdi:waypoint>116</bpmndi:BPMNEdge>117</bpmndi:BPMNPlane>118</bpmndi:BPMNDiagram>119 </definitions>用一个userType=1的用户测试一下
1 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 23 RepositoryService repositoryService = processEngine.getRepositoryService(); 4 RuntimeService runtimeService = processEngine.getRuntimeService(); 5 TaskService taskService = processEngine.getTaskService(); 67 Deployment deployment = repositoryService.createDeployment() 8.addClasspathResource("diagram/HealthExamination.bpmn") 9.addClasspathResource("diagram/HealthExamination.png")10.name("体检流程")11.key("HealthExamination")12.deploy();13 14 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()15.deploymentId(deployment.getId())16.singleResult();17 System.out.println(processDefinition.getId());18 19 20 Map<String, Object> variables = new HashMap<>();21 variables.put("username", "cheng");22 variables.put("userType", 1);23 24 //启动流程实例25 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("HealthExamination", variables);26 System.out.println(processInstance.getId());27 28 //查询cheng的待办任务29 Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee("cheng").singleResult();30 if (null != task) {31taskService.complete(task.getId());32 }33 34 //断言进入包含网关之后cheng有两个待办任务,因为他的userType=135 List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();36 Assertions.assertEquals(2, taskList.size()); 
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
1 Map<String, Object> variables = new HashMap<>(); 2 variables.put("username", "chengcheng"); 3 variables.put("userType", 2); 45 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("HealthExamination", variables); 67 Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskAssignee("chengcheng").singleResult(); 8 if (null != task) { 9taskService.complete(task.getId());10 }11 12 List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();13 Assertions.assertEquals(3, taskList.size());
activities怎么读 Activiti7 入门篇

文章插图

activities怎么读 Activiti7 入门篇

文章插图
 
相关文档
https://www.activiti.org/ 
https://camunda.com/bpmn/
https://bpmn.io/
http://www.pangubpm.com/ 
【activities怎么读 Activiti7 入门篇】http://www.yunchengxc.com/