Activiti7
什么工作流引擎
框架,将业务数据和节点的流程进行分离【特定形式进行关联】,实现节点的自动流转的工作流框架.,帮助我们实现流程自动化。
使用情景:也称为工作流
请假审批:填写申请–>主管部门–>HR审批
报销审批:填写申请–>经理批准–>总经理–>财务批准
虽然不用框架也能实现该业务需求,流程变得复杂,需要改动时,就需要耗费大量的时间成本
Activiti7框架就是这样开源出来的一套框架,可以做到流程与代码分离,帮助我们实现
一、Activiti7的内部核心机制
- 业务流程图需要符合规范
- 业务流程图的本质就是xml文件,里面的数据就是一个个的节点
- 解析业务流程图的过程就是解析xml文件,读取数据的过程
- 读取节点就是把数据存到数据库中,形成一条条的记录
- 后续我们只要对表进行查询就能知道流程走到哪一步 ru_task
- 任务完成提交就是更改数据库中表的记录,再读取下一个节点的数据
- 流程接受后,更改表的记录
二、BPMN
制定了一套规范,也就是业务流程图
三、使用Activiti
1. 流程:
- 业务流程建模,画业务流程图
- 部署业务流程,定义业务流程,可以理解为定义一个类,关联业务流程图 …bpmn
- 启动业务流程,流程实例,可以理解为创建对象
- 查询任务
- 执行任务
- 结束流程,如果没有下一个结点,就是任务完成
2. 环境:
- jdk1.8或以上
- mysql5或以上
- Tomcat8.5
- IDEA
- Activiti 7.0.0.SR1
3. 安装Activiti流程设计器(画图工具)
4.处理中文乱码
5.支持的数据库
四、集成Activiti7
SE环境,基于maven项目
1. 添加依赖
<!--添加依赖-->
<properties>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<activiti.version>7.0.0.SR1</activiti.version>
</properties>
<dependencies>
<!-- activiti引擎 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- 整合Spring -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 模型处理 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn json数据转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 布局 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 链接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
2. 添加日志文件
在resource文件夹中创建log4j.properties文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=./activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
3.添加核心配置文件
在resource文件夹中创建名为 activiti.cfg.xml 的文件,文件名是固定的,不按规则命名会报错
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--添加数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///activiti"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
</bean>
<!-- 默认id对应的值 为processEngineConfiguration -->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<!--
activiti数据库表处理策略
false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常
true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。
create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。
drop-create:先删除表再创建表。
create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表
-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
五、数据库表的说明
1. 介绍
Activiti是通过操作数据库中的表单来实现工作流的。不同的环境中,表的数量也是不一样的。
此环境中有25张表。
- 每一种表都对应着一个Service
- 命名规则
- "act_re"开头的表,re表示 Repository,与流程定义有关
- "act_ru"开头的表,,ru表示RunTime,与流程实例,任务处理有关,只保存正在执行中的任务的数据
- "act_hi"开头的表,,hi表示History,记录流程,变量,任务等的历史信息
- "act_ge"开头的表,ge表示General,记录通用数据
2. 常用表
-
流程定义—>RepositoryService
-
act_ge_bytearray:用于存储bpmn的数据
-
act_ge_property:用于生产主键等,是内部表,我们一般不需要关注
-
act_re_deployment:部署信息表
-
act_re_procdef:流程定义表
-
-
流程实例—>RunTimeService
- act_ge_property:主键更新
- act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
- act_hi_identitylink:历史身份表,记录所有用户的信息
- act_hi_procinst:历史流程表:记录所有流程实例的信息
- act_hi_taskinst:历史任务表:记录所有任务对象的信息
- act_ru_execution:运行时流程执行实例表
- act_ru_identitylink:运行时用户信息表,
- act_ru_task:运行时任务信息表
-
执行任务—>taskService
- act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
- act_hi_identitylink:历史身份表,记录所有用户的信息
- act_hi_taskinst:历史任务表:记录所有任务对象的信息
- act_ru_execution:运行时流程执行实例表
- act_ru_identitylink:运行时用户信息表,
- act_ru_task:运行时任务信息表
六、流程引擎的API
接口 | 作用 |
---|---|
RepositoryService | 进行资源管理,流程定义 |
RunTImeService | 进行流程实例 |
TaskService | 进行任务管理 |
HistoryService | 进行历史管理 |
ManagementService | 进行引擎管理 |
七、Activiti7的入门
1. bpmn的制作
bpmn的id和Name是自定义的
给任务节点设置名字,给上执行人,后续执行人可以使用UEL表达式,监听器来设置,也可以通过候选人方式设置。
2. 流程定义
@Test
public void test1() {
//1 获取流程引擎对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2 获取仓库Service, RespositoryService
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("bpmn/act3.bpmn")
.deploy();
//一个deploye对应一个流程定义
}
3.流程实例
@Test
public void test2() {
processEngine.getRuntimeService()
.startProcessInstanceByKey("bpmn图中id");//自定义的流程名称
}
4.执行任务
@Test
public void test3(){
/*
参数为该任务的id,可以用TaskService提供query方法进行任务的查询
添加评论要在任务提交前执行
添加评论 taskService.addComent(taskId,processInstanceId,messag);
多个对象用list(),唯一用singleResult()
*/
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
taskService
.createTaskQuery()
.processDefinitionKey("leaveProcess")//查询条件
.taskAssignee("张三")//查询条件
.list().forEach(task -> {
taskService.addComment(task.getId(), task.getProcessInstanceId(), "不干了");
taskService.complete(task.getId());
});
}
5.查看历史情况
@Test
public void test10() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
historyService.createHistoricProcessInstanceQuery()
.processDefinitionKey("leaveProcess")
.list()
.forEach(historicProcessInstance -> {
System.out.println(historicProcessInstance.getId());
});
}
八、Activiti7的进阶
一、流程定义相关
- 查询流程相关信息,包含流程定义,流程部署,流程定义版本
@Test
public void testDefinitionQuery(){
//创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取流程定义集合
List<ProcessDefinition> processDefinitionList = repositoryService
.createProcessDefinitionQuery()
.processDefinitionKey("leaveProcess")
.list();
//遍历集合
for (ProcessDefinition definition:processDefinitionList){
System.out.println("流程定义ID:"+definition.getId());
System.out.println("流程定义名称:"+definition.getName());
System.out.println("流程定义key:"+definition.getKey());
System.out.println("流程定义版本:"+definition.getVersion());
System.out.println("流程部署ID:"+definition.getDeploymentId());
System.out.println("====================");
}
}
2.现在我们的流程资源文件已经上传到数据库了,如果其他用户想要查看这些资源文件,可以从数据库中把资源文件下载到本地。
@Test
public void testDownloadResource() throws Exception {
//创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取流程定义集合
List<ProcessDefinition> list = repositoryService
.createProcessDefinitionQuery()
.processDefinitionKey("leaveProcess")
.orderByProcessDefinitionVersion()//按照版本排序
.desc()//降序
.list();
//获取最新那个
ProcessDefinition definition =list.get(0);
//获取部署ID
String deploymentId = definition.getDeploymentId();
//获取bpmn的输入流
InputStream bpmnInput = repositoryService.getResourceAsStream(
deploymentId,
definition.getResourceName());
//获取png的输入流
InputStream pngInput = repositoryService.getResourceAsStream(
deploymentId,
definition.getDiagramResourceName());
//设置bpmn输入
FileOutputStream bpmnOutPut = new FileOutputStream("D:/leave.bpmn");
//设置png输入
FileOutputStream pngOutPut = new FileOutputStream("D:/leave.png");
IOUtils.copy(bpmnInput,bpmnOutPut);
IOUtils.copy(pngInput,pngOutPut);
}
3.根据部署Id删除对应的流程定义
如果流程定义 没有流程实例可以直接删除
如果流程定义 已近有流程实例,可以通过一个参数 true 进行级联删除
@Test
public void test3(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService().deleteDeployment("5001",true);
}
二、流程实例相关
框架,将业务数据和节点的流程进行分离【特定形式进行关联】,特定形式指的就是businessKey
businessKey
搞清楚businessKey 作用?
把我们的业务数据和流程绑定起来 , 因为在审核的时候 , 审核人妖看到用户申请信息.
步骤
1 用户在申请的时候填写信息 ,最终把信息保存到业务表中
2 先画出bpmn流程 ,把流程图 部署到activiti当中
3 小陈发起申请, 在activiti 开启流程实例 , 在启动流程时候就会把businessKey 和流程实例绑定起来
4 任务走了部门经理节点 , 这里是一个任务, 我们是可以通过任务拿到流程实例id
5 通过流程实例id拿到流程实例 , 就可以通过流程实例那businessKey
6 根据businessKey 上业务表中取查询数据 , 审核人在根据查询的数据看是否通过
public class Demo {
/**
* 获取businessKey
*/
//流程定义
@Test
public void test1() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("bpmn/act3.bpmn")
.deploy();
}
//流程实例+添加businessKey
@Test
public void test2() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceByKey("act3", "2887");
}
//在任务中获取实例id,通过实例id获取实例对象,通过实例对象获取businessKey
@Test
public void test3() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String processInstanceId = processEngine.getTaskService()
.createTaskQuery()
.singleResult()
.getProcessInstanceId();
String businessKey = processEngine
.getRuntimeService()
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult()
.getBusinessKey();
System.out.println("businessKey = " + businessKey);
}
}
三、流程定义/实例挂起/激活
例如公司制度改变过程中的流程, 总经理更换过程中的流程,有100个人的流程, 70个人已经完成,30个人流程正好在总经理更换中,就需要挂起.
- 比如我们的业务流程为:
【开始节点】–>【A节点】–>【B节点】–>【C节点】–>【结束节点】
【C节点】的业务逻辑需要和外部接口交互,刚好外部接口出问题了,如果剩下的流程都走到【C节点】,执行【C节点】的业务逻辑,那都会报错,我们就可以把流程挂起,等待外部接口可用之后再重新激活流程.
- 业务流程发生改变,已经发起的流程实例继续按照旧的流程走,如果新发起的流程就按照新的业务流程走.这时候我们就需要挂起流程定义,但是不挂起流程实例.
- 操作流程定义为挂起状态,该操作定义下面的所有的流程实例将全部暂停。
- 流程定义为挂起状态,该流程定义下将不允许启动新的流程实例,同时该流程定义下的所有流程实例将全部挂起暂停执行
public class Demo {
/**
* 流程定义的挂起与激活
*/
//定义流程
@Test
public void test1() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("bpmn/act4.bpmn")
.deploy();
}
//流程实例
@Test
public void test2() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceByKey("act4");
}
//进行流程挂起
@Test
public void test3() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessDefinition processDefinition = processEngine.getRepositoryService().
createProcessDefinitionQuery()
.singleResult();
processEngine.getRepositoryService().suspendProcessDefinitionById(processDefinition.getId());
}
//查询流程挂起状态
@Test
public void test4() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.singleResult().isSuspended());//true
}
//可以完成未完成的任务
@Test
public void test5() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Task task = processEngine.getTaskService()
.createTaskQuery()
.singleResult();
processEngine.getTaskService().complete(task.getId());
}
//但不能再流程实例
@Test
public void test6() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceByKey("act4");
}
//重新激活流程定义+测试+执行新实例任务
@Test
public void test7() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.singleResult();
if (processDefinition.isSuspended()) {
System.out.println("to true");
repositoryService.activateProcessDefinitionById(processDefinition.getId());
System.out.println("流程实例");
processEngine.getRuntimeService()
.startProcessInstanceByKey("act4");
System.out.println("执行任务");
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery().taskAssignee("张三").singleResult();
taskService.complete(task.getId());
}
}
//挂起后不能执行任务和进行流程定义
@Test
public void test8() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.singleResult();
repositoryService
.suspendProcessDefinitionById(processDefinition.getId(), true, null);
}
//不能进行流程定义
@Test
public void test9(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceByKey("act4");
}
//不能执行任务
@Test
public void test10(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService().complete("10005");
}
//挂起实例
@Test
public void test11(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//把原来的挂起的流程定义激活
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.singleResult();
//挂起实例
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.suspendProcessInstanceById("10001");
//检测是否挂起,若已近挂起,就重新激活,并执行任务
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.taskAssignee("张三")
.singleResult();
//获取实例id
String processInstanceId = task.getProcessInstanceId();
//判断是否已近挂起
boolean suspended = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult()
.isSuspended();
if (suspended) {
System.out.println("======================");
System.out.println("激活");
runtimeService.activateProcessInstanceById(processInstanceId);
taskService.complete(task.getId());
}
}
}
三、任务分配
指的就是指定处理任务的人,分配方法有三种
1.固定分配 直接把名字写死,在实际开发过程中,此方法不适应。但在测试时使用比其他的方法都方便。
只要在任务结点中的 Assignee属性中设置值
-
使用EUL表达式,是一种占位符,在任务结点中的 Assignee属性中设置${value}。需要把处理人添加到流程实例,就要在流程实例时,添加参数 ,以map的方式添加。
public class UEL { /** * 分配负责人 */ //流程定义 @Test public void test1() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); processEngine.getRepositoryService() .createDeployment() .addClasspathResource("bpmn/act5.bpmn") .deploy(); } //实例部署 @Test public void test2() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); Map<String, Object> map = new HashMap<>(); map.put("s1", "张三"); map.put("s2", "lisi"); processEngine.getRuntimeService() .startProcessInstanceByKey("act5", map); } //查询候选人 @Test public void test3() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); Task lisi = processEngine.getTaskService() .createTaskQuery() .taskCandidateOrAssigned("lisi").singleResult(); } //领任务 @Test public void test4(){ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); processEngine.getTaskService().claim("17507","lisi"); } //执行任务 @Test public void test5(){ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); processEngine.getTaskService().complete("17507"); } }
-
监听器
任务监听器是发生对应的任务相关事件时执行自定义的Java逻辑或表达式。
任务相关事件包括:
- Event:触发事件
- Create:任务创建后触发。
- Assignment:任务分配后触发。
- Delete:任务完成后触发。
- All:所有事件发生都触发。
- Event:触发事件
-
自定义一个任务监听器类,然后此类必须实现org.activiti.engine.delegate.TaskListener接口
package cn.wolfcode; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.delegate.TaskListener; /** * Created by wolfcode */ public class AssigneeTaskListener implements TaskListener { public void notify(DelegateTask delegateTask) { if(delegateTask.getName().equals("部门经理审批")){ delegateTask.setAssignee("赵六"); }else if(delegateTask.getName().equals("部门经理审批")){ delegateTask.setAssignee("孙七"); } } }
-
在bpmn文件中配置监听器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzt3J72y-1653831176864)(E:/CodeWolf/20220215/阶段四/07 Activit/讲义/图片/image-20210603114503828.png)]
在实际开发中,一般也不使用监听器分配方式,太麻烦了。
-
四、流程变量
在流程中,可以通过变量来控制流程的走向,从而增强业务能力。
- 局部变量(少用)
- 全局变量(多用)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GXacHjjK-1653831176865)(C:\Users\SKY\AppData\Roaming\Typora\typora-user-images\image-20220529172114148.png)]
3. 使用方法
1. 在流程实例时,添加一个map为参数,Map<String,Object> ,String为变量名,Object为值
4. 特殊情况
1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
2. 当两个情况都不满足时,会抛出异常,说找不到出口
五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
2. 使用 taskSerice.commit(Strinig taskId)执行任务
六、网关
-
排他网关
- 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
- 如果分支都为true,就会选择id小的分支
- 当分支都为false时,会报错,说流程找不到出口
-
并行网关
- 需要两个网关,把所有分支都夹起来
- 只有里面的分支全都走完,流程才能到下一个结点
-
包含网关
-
可以看成是排他网关与并行网关的集合体
-
需要两个网关,把所有分支都夹起来
-
使用场景:请假规则
- 请假<3天的副经理批准
- 请假>3天的总经理批准
- 请假无论多少天都需要人事部门批准
-
候选人,需要先使用claim进行领取任务,在执行任务
g为变量名,Object为值
4. 特殊情况
1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
2. 当两个情况都不满足时,会抛出异常,说找不到出口
五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
2. 使用 taskSerice.commit(Strinig taskId)执行任务
六、网关
-
排他网关
- 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
- 如果分支都为true,就会选择id小的分支
- 当分支都为false时,会报错,说流程找不到出口
-
并行网关
- 需要两个网关,把所有分支都夹起来
- 只有里面的分支全都走完,流程才能到下一个结点
-
包含网关
-
可以看成是排他网关与并行网关的集合体
-
需要两个网关,把所有分支都夹起来
-
使用场景:请假规则
- 请假<3天的副经理批准
- 请假>3天的总经理批准
- 请假无论多少天都需要人事部门批准
-