1、关于Activiti
初学activiti我关心的它是什么东西、有什么功能、怎么实现?
先来看一张流程图感受一下:
activiti是一个业务流程管理引擎,它的流程图大概就像是列车的轨道,而所要执行的对象像是一辆自动运行的列车,只要列车启动,它就能沿着轨道一直走到终点,而其中的节点就像是列车到达终点途中所要经过的火车站,它会告诉火车下一站是哪里,然后火车就往指定的下一站驶去,直到终点,流程结束。
如上所描述,最主要的功能就是实现了代码的自动按流程执行
关于怎么实现,既然这是一个框架,自然就是引进jar包,画流程图,然后实现该框架提供的接口来做我们想要做的事情。
2、Activiti数据库的理解
activiti在每个节点都能知道下一个节点是什么,以及当前任务是什么,那势必会有存储流程的各种信息的表。事实也确实如此,activiti可以配置数据库,其中存储了流程运行时的相关信息。在初学Activiti之时,了解activiti所有的数据库表的含义对理解activiti工作机制是有很大帮助的,activiti总共涉及的表格总共有23个:
act_ge_*:general通用数据,用于存放数据。
act_re_*:reposity类似于仓库,存放流程定义文件和流程图片文件,比如一个流程部署之后可以在act_re_deployment表中看到。
act_ru_*:run服务运行时候的数据,当一个流程启动之后当前的活动任务可以在act_ru_task表格中查看 ,以及流程中所有的变量都保存在act_ru_variable表格当中。
本来想写一系列完整的Activiti的学习笔记的,但是学完之后发现工作量着实不小,自身学的也不够深,况且网上大有牛人有类似的学习笔记,所以此文权当是个人学习activiti的过程中填坑记录,仅供参考;
3、运行环境搭建,最简单的运行环境(学习中用到了Junit 4用来测试很好用。),eclipse+jar包+mysql,配置文件,因为我这里没有与Spring整合,所以配置文件就一个activiti.cfg.xml放在class_path下面就好了。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
//数据库配置
configuration.setJdbcDriver("com.mysql.jdbc.Driver");
configuration.setJdbcUrl("jdbc:mysql://localhost:3306/itcast0621activiti?useUnicode=true&characterEncoding=utf8");
configuration.setJdbcUsername("root");
configuration.setJdbcPassword("root");
configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lewinactiviti?useUnicode=true&characterEncoding=utf8"></property>
<property name="jdbcUsername" value="root"></property>
<property name="jdbcPassword" value="123456"></property>
<!--
创建表的策略
-->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
4、下载画流程工具activiti-app.war
从官网下载war包(登录用户密码:admin test),找到activiti-app.war放进tomcat,启动之后自己画一个流程图,用于下面的测试
war包下载:https://www.activiti.org/down...
版本6.xx的相关文档都在这里:https://www.activiti.org/docs
版本5.xx的官网好像不再维护了
[画图工具]
5、开始实现Activiti的一些api,并查看表格中的变化
package com.lewin.activiti.taskListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
public class DepolyTest {
@Test
public void run(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
//.addClasspathResource("taskListener.bpmn20.xml")
.addClasspathResource("UserExecuteTask.bpmn20.xml")
.deploy();
String piid = deployment.getId();
System.out.println("processDefinitionId:"+piid);
//String processKey = "lewin";
String processKey = "UserExecuteTask";
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processKey);
System.out.println(pi.getId());
}
/**
* 根据流程定义里的id启动流程实例
*/
public void startInstance(){
String processInstanceKey = "lewin";
//“lewin”即对应着流程定义中的id值
ProcessInstance pi = ProcessEngines.getDefaultProcessEngine()
.getRuntimeService()
.startProcessInstanceByKey(processInstanceKey);
System.out.println("started processInstance id is:"+processInstanceKey+"; pi.id is:"+pi.getId());
}
/*
* 从class_path中部署流程实例
*/
@Test
public void deploymentProcessDefinition_classpath(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()//获取仓库服务
.createDeployment()//创建部署实例
.name("deploymentName")//设置将要部署的流程实例的名称
.addClasspathResource("taskListener.bpmn20.xml")//资源文件:默认路径在class_path下面
//.addClasspathResource("diagrams/HelloWorld.png")
.deploy();//部署
System.out.println("id:"+deployment.getId());
System.out.println("name:"+deployment.getName());
}
/*
* 查询定义了的流程
* 查询内容来自act_re_deployment
*/
@Test
public void findProcessDefinition(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
//.deploymentId(deploymentId)
//.processDefinitionId(processDefinitionId)
//.processDefinitionKey(processDefinitionKey)
//.processDefinitionNameLike(processDefinitionNameLike)
.orderByProcessDefinitionVersion().asc()
//.orderByProcessDefinitionName().desc()
.list();
//.singleResult();
//.count();
//.listPage(firstResult, maxResults)
if(list != null && list.size()>0){
for(ProcessDefinition processDefinition:list){
System.out.println("ID:"+processDefinition.getId());
System.out.println("NAME:"+processDefinition.getName());
System.out.println("KEY:"+processDefinition.getKey());
System.out.println("VERSION:"+processDefinition.getVersion());
System.out.println("resourceName:"+processDefinition.getResourceName());
System.out.println("图片名字:"+processDefinition.getDiagramResourceName());
System.out.println("部署的流程id:"+processDefinition.getDeploymentId());
System.out.println("################################");
}
}
}
/*
* 删除流程定义
*/
@Test
public void deleteProcessDefinition(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程定义id
String deploymentId = "2201";
processEngine.getRepositoryService()
.deleteDeployment(deploymentId, true);
System.out.println("删除成功!");
}
/*
* 查看流程定义图并下载到本地
*/
@Test
public void viewPic() throws IOException{
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**流程部署id*/
String deploymentId = "201";
//根据id获取存储在act_re_deployment表里面的静态资源,里面就有图片
List<String> list = processEngine.getRepositoryService()//
.getDeploymentResourceNames(deploymentId);
//获取名字
String resourceName = "";
if(list!=null && list.size()>0){
for(String name:list){
if(name.indexOf(".png")>=0){
resourceName = name;
}
}
}
//获取图片资源
InputStream in = processEngine.getRepositoryService()//
.getResourceAsStream(deploymentId, resourceName);
//新建文件
File file = new File("D:/"+resourceName);
//文件复制
FileUtils.copyInputStreamToFile(in, file);
}
/*
* 删除路程定义根据定义中的名字
*/
@Test
public void deleteProcessDefinitionByKey(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程定义文件中的名字,如果相同名字有多个默认使用版本最高的那个
String processDefinitionKey = "UserExecuteTask";
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.processDefinitionKey(processDefinitionKey)
.list();
//删除所有名字为UserExecuteTask的流程定义
if(list!=null && list.size()>0){
for(ProcessDefinition pd:list){
//获取ID
String deploymentId = pd.getDeploymentId();
processEngine.getRepositoryService()
.deleteDeployment(deploymentId);
}
}
}
/**
* 查询流程状态
*/
@Test
public void queryInstanceState(){
//流程id
String instanceId = "1309";
//任务id
String taskId = "1312";
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//通过流程id查询状态
ProcessInstance pi = processEngine.getRuntimeService()
.createProcessInstanceQuery()//创建查询
.processInstanceId(instanceId)//根据id
.singleResult();//获取状态
if(pi!=null){
System.out.println("id为"+instanceId+"的流程正在进行中......");
//完成当前节点
processEngine.getTaskService().complete(taskId);
}else{
System.out.println("id为"+instanceId+"的流程已经完成!");
}
}
/**
* 查询流程执行对象
*/
@Test
public void queryExecution(){
//查询执行对象
String exe = "User Task";
//获取流程实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//查询
Execution e1 = processEngine.getRuntimeService()
.createExecutionQuery()
.processInstanceId("1509")
.activityId(exe)
.singleResult();
if(e1!=null){
System.out.println("e1!=null");
}else{
System.out.println("e1==null");
}
}
/**
* 根据用户查询任务
*/
@Test
public void queryUserTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// Fetch all tasks for the management group
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
System.out.println("Task available: " + task.getName());
}
}
}
6、例子1:只有用户任务和并行网关的运行
UserExecuteTask.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:activiti="http://activiti.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="daling">
<process id="UserExecuteTask" name="UserExecuteTask">
<!-- 开始和结束监听事件 -->
<extensionElements>
<activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
<activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
</extensionElements>
<!-- 开始和结束监听事件结束 -->
<startEvent id="startevent1" name="Start"></startEvent>
<parallelGateway id="parallelgateway1" name="start"></parallelGateway>
<userTask id="servicetask1" name="servicetask1" >
<extensionElements>
<activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.DeveloperManagerUserTaskListener"/>
</extensionElements>
</userTask>
<userTask id="servicetask2" name="servicetask2">
<extensionElements>
<activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.ProductManagerUserTaskListener"/>
</extensionElements>
</userTask>
<userTask id="servicetask3" name="servicetask3" >
<extensionElements>
<activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.TeamLeaderUserTaskListener"/>
</extensionElements>
</userTask>
<parallelGateway id="parallelgateway2" name="First Join"></parallelGateway>
<userTask id="servicetask4" name="servicetask4" >
<extensionElements>
<activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.ProductBossUserTaskListener"/>
</extensionElements>
</userTask>
<parallelGateway id="parallelgateway3" name="parallelgateway3"></parallelGateway>
<userTask id="servicetask5" name="servicetask5" >
<extensionElements>
<activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.HumanResouceUserTaskListener"/>
</extensionElements>
</userTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="parallelgateway1" targetRef="servicetask1"></sequenceFlow>
<sequenceFlow id="flow3" name="" sourceRef="parallelgateway1" targetRef="servicetask2"></sequenceFlow>
<sequenceFlow id="flow4" name="" sourceRef="parallelgateway1" targetRef="servicetask3"></sequenceFlow>
<sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow6" name="" sourceRef="servicetask2" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow7" name="" sourceRef="servicetask3" targetRef="parallelgateway3"></sequenceFlow>
<sequenceFlow id="flow8" name="" sourceRef="parallelgateway2" targetRef="servicetask4"></sequenceFlow>
<sequenceFlow id="flow9" name="" sourceRef="servicetask4" targetRef="parallelgateway3"></sequenceFlow>
<sequenceFlow id="flow10" name="" sourceRef="parallelgateway3" targetRef="servicetask5"></sequenceFlow>
<sequenceFlow id="flow11" name="" sourceRef="servicetask5" targetRef="endevent1"></sequenceFlow>
</process>
</definitions>
测试代码:
/**
* 对应UserExecuteTask.bpmn20.xml
* 这是一个用户任务,所以流程完全执行需要用户的参与
* 获取所有任务
*
*/
@Test
public void getAllTasks(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库实例
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("UserExecuteTask.bpmn20.xml")
.deploy();
//启动流程实例
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey("UserExecuteTask");
System.out.println("pi.id:"+pi.getId());
//第一轮(流程启动之后自动进入下一级节点,
//下一级节点为并行的三个任务,获取该三个任务依次按定义文件中顺序完成)
TaskService taskService = processEngine.getTaskService();
TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();
List<Task> tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
//第二轮查询任务:上一轮三个任务依次完成之后开始进入下一轮,第二级节点
tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
//第三轮查询任务:上一轮一个任务完成之后,开始进入下一级节点,
//即最后的人事部门审批
tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
}
运行结果:
7、例子2:只有系统任务和并行网关的运行
AutoUserExecuteTask.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:activiti="http://activiti.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.activiti.org/test">
<process id="AutoUserExecuteTask" name="AutoUserExecuteTask">
<!-- 开始和结束监听事件 -->
<extensionElements>
<activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
<activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
</extensionElements>
<!-- 开始和结束监听事件结束 -->
<startEvent id="startevent1" name="Start"></startEvent>
<parallelGateway id="parallelgateway1" name="多种请假方式"></parallelGateway>
<serviceTask id="servicetask1" name="项目经理同意" activiti:class="com.lewin.activiti.UserExecuteService.DeveloperManagerServiceTask"></serviceTask>
<serviceTask id="servicetask2" name="产品经理同意" activiti:class="com.lewin.activiti.UserExecuteService.ProductManagerServiceTask"></serviceTask>
<serviceTask id="servicetask3" name="项目组长同意" activiti:class="com.lewin.activiti.UserExecuteService.TeamLeaderServiceTask"></serviceTask>
<parallelGateway id="parallelgateway2" name="First Join"></parallelGateway>
<serviceTask id="servicetask4" name="项目总监同意" activiti:class="com.lewin.activiti.UserExecuteService.ProductBossServiceTask"></serviceTask>
<parallelGateway id="parallelgateway3" name="人事判断"></parallelGateway>
<serviceTask id="servicetask5" name="人事部门同意" activiti:class="com.lewin.activiti.UserExecuteService.HumanResouceServiceTask"></serviceTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="parallelgateway1" targetRef="servicetask1"></sequenceFlow>
<sequenceFlow id="flow3" name="" sourceRef="parallelgateway1" targetRef="servicetask2"></sequenceFlow>
<sequenceFlow id="flow4" name="" sourceRef="parallelgateway1" targetRef="servicetask3"></sequenceFlow>
<sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow6" name="" sourceRef="servicetask2" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow7" name="" sourceRef="servicetask3" targetRef="parallelgateway3"></sequenceFlow>
<sequenceFlow id="flow8" name="" sourceRef="parallelgateway2" targetRef="servicetask4"></sequenceFlow>
<sequenceFlow id="flow9" name="" sourceRef="servicetask4" targetRef="parallelgateway3"></sequenceFlow>
<sequenceFlow id="flow10" name="" sourceRef="parallelgateway3" targetRef="servicetask5"></sequenceFlow>
<sequenceFlow id="flow11" name="" sourceRef="servicetask5" targetRef="endevent1"></sequenceFlow>
</process>
</definitions>
测试代码:
/**
* 对应UserExecuteTask.bpmn20.xml
* 这是一个自动任务(不包含用户任务),所以流程完全执行不需要用户的参与
* 只需要启动实例,流程会自动按流程走完
* 获取所有任务
*
*/
@Test
public void autoRun(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库实例
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("AutoUserExecuteTask.bpmn20.xml")
.deploy();
//启动流程实例
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey("AutoUserExecuteTask");
System.out.println("pi.id:"+pi.getId());
}
运行结果:
![图片上传中...]
8、例子3:只有用户任务和排他网关的运行
ExclusiveGatawayDemo.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:activiti="http://activiti.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.activiti.org/processdef">
<process id="ExclusiveGatawayDemo" name="ExclusiveGatawayDemo" isExecutable="true">
<documentation>ExclusiveGatawayDemo</documentation>
<extensionElements>
<activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
<activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
</extensionElements>
<startEvent id="start" name="start"></startEvent>
<userTask id="userTask1" name="userTask1">
<extensionElements>
<activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.DeveloperManagerUserTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227" sourceRef="start" targetRef="userTask1"></sequenceFlow>
<exclusiveGateway id="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19"></exclusiveGateway>
<sequenceFlow id="sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483" sourceRef="userTask1" targetRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19"></sequenceFlow>
<userTask id="userTask2" name="userTask2">
<extensionElements>
<activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.ProductManagerUserTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="userTask3" name="userTask3">
<extensionElements>
<activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.TeamLeaderUserTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
<endEvent id="end" name="end"></endEvent>
<sequenceFlow id="sid-2C04111C-D70E-414A-88C4-980B52F9D5AA" sourceRef="userTask2" targetRef="end"></sequenceFlow>
<sequenceFlow id="sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC" sourceRef="userTask3" targetRef="end"></sequenceFlow>
<sequenceFlow id="sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43" sourceRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" targetRef="userTask2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${myCondition=="userTask2"}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41" sourceRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" targetRef="userTask3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${myCondition=="userTask3"}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_ExclusiveGatawayDemo">
<bpmndi:BPMNPlane bpmnElement="ExclusiveGatawayDemo" id="BPMNPlane_ExclusiveGatawayDemo">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="30.0" width="30.0" x="105.0" y="119.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="userTask1" id="BPMNShape_userTask1">
<omgdc:Bounds height="80.0" width="100.0" x="270.0" y="94.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" id="BPMNShape_sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19">
<omgdc:Bounds height="40.0" width="40.0" x="500.5" y="114.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="userTask2" id="BPMNShape_userTask2">
<omgdc:Bounds height="80.0" width="100.0" x="720.0" y="94.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="userTask3" id="BPMNShape_userTask3">
<omgdc:Bounds height="80.0" width="100.0" x="720.0" y="255.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="28.0" width="28.0" x="999.5" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227" id="BPMNEdge_sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227">
<omgdi:waypoint x="135.0" y="134.0"></omgdi:waypoint>
<omgdi:waypoint x="270.0" y="134.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483" id="BPMNEdge_sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483">
<omgdi:waypoint x="370.0" y="134.0"></omgdi:waypoint>
<omgdi:waypoint x="500.5" y="134.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41" id="BPMNEdge_sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41">
<omgdi:waypoint x="521.0" y="153.5"></omgdi:waypoint>
<omgdi:waypoint x="521.0" y="295.0"></omgdi:waypoint>
<omgdi:waypoint x="720.0" y="295.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43" id="BPMNEdge_sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43">
<omgdi:waypoint x="540.0382293762575" y="134.46177062374247"></omgdi:waypoint>
<omgdi:waypoint x="720.0" y="134.1004016064257"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC" id="BPMNEdge_sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC">
<omgdi:waypoint x="820.0" y="295.0"></omgdi:waypoint>
<omgdi:waypoint x="1012.5" y="295.0"></omgdi:waypoint>
<omgdi:waypoint x="1012.5" y="158.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-2C04111C-D70E-414A-88C4-980B52F9D5AA" id="BPMNEdge_sid-2C04111C-D70E-414A-88C4-980B52F9D5AA">
<omgdi:waypoint x="820.0" y="134.0"></omgdi:waypoint>
<omgdi:waypoint x="999.5" y="134.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
测试代码:
/**
* 对应ExclusiveGatewayDemo.bpmn20.xml
* 包含排他网关的流程
* 获取所有任务
*
*/
@Test
public void exclusiveGatewayTasks(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库实例
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("ExclusiveGatawayDemo_Deploymentname")
.addClasspathResource("ExclusiveGatawayDemo.bpmn20.xml")
.deploy();
//启动流程实例
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey("ExclusiveGatawayDemo");
System.out.println("pi.id:"+pi.getId());
//第一轮(流程启动之后自动进入下一级节点,
//下一级节点为并行的三个任务,获取该三个任务依次按定义文件中顺序完成)
TaskService taskService = processEngine.getTaskService();
TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();
List<Task> tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
/**
* userTask1完成,并且设置变量“myCondition”
* 这里测试设置的值是"userTask3"
* 按照定义应该执行userTask3
* 注释下面代码的情况下,查询act_ru_task可以查看到有userTask3任务
* 不注释的情况下,流程完成userTask1和userTask3走完整个流程
*/
//第二轮查询任务:上一轮三个任务依次完成之后开始进入下一轮,第二级节点
tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
//第三轮查询任务:上一轮一个任务完成之后,开始进入下一级节点,
//即最后的人事部门审批
tasks = query.list();
//循环打印tasks的信息
for(Task task : tasks){
//执行任务 ,完成任务
taskService.complete(task.getId());
System.out.println("name ="+task.getName());
System.out.println(tasks.size());
}
}
运行结果:
字数不够,代码来凑,草草结束,细节之处多有遗漏,有一起学习的有问题的可以私信。强行回顾了一下前两天的学习历程。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。