一、连线
与JBPM中用Decision做判断不同,Activiti中的判断条件写在连线(SequenceFlow)中
当有多个连线时:
1、点击连线,选择Properties中的General,填写Name属性用于解释该连线的判断依据(只为方便理解)
2、选择Main config,填写Condition判断条件属性:
一般在,流程启动或前一任务完成时,会赋值判断条件的变量,如:
Map<String,Object> variables = new LinkedHashMap<String,Object>();
variables.put("money", 100);
taskService.complete(taskId,variables);//完成任务
则可在Condition中添加判断条件:${变量名 op 判断值} PS:判断条件必须为boolean类型的返回值
如: ${money>=1000} ${message== '重要'}
PS、1、对于多出度的节点,不使用网关,直接使用连线连接多个其他节点,相当于排他网关(只选其中符合条件的一条连线输出)
2、如果判断条件需要变量参与,而变量没有赋值,则会报错。
只有一个连线时可不设置条件,流程自动执行下一个任务。
开始event只可有一个输出连线,结束event可有输入连线,不可有输出连线。
二、排他网关(ExclusiveGateway)
1、一个排他网关对应一个以上输出流。
如
2、由排他网关流出的输出流都有个conditionExpression元素(如下图的Condition),返回boolean类型的决策结果。
3、决策网关只会返回一条结果,执行到排他网关时,流程引擎自动按序检索出口(可通过右键.bpmn文件->Open With->XML Editor,查看流程定义源代码),
直到找到第一条决策结果为true或未设置条件(视为true)的出口流出。若无,则依默认连线离开。(没有匹配条件又无默认连线,则抛出异常)。
如下图,可通过选择排他网关进行默认连线设置
三、并行网关(ParallelGateway)
对于JBPM,并行网关的分支节点需使用fork,汇聚节点使用join,而activiti工作流统一使用ParallelGateway。
1、一个并行网关对应一个以上输出流,同时输出至所有出口。
2、执行到并行网关时,同一个流程实例会创建出多个执行对象(创建个数与网关出口数相同),原执行对象仍在,可查询act_ru_execution(运行中执行对象表)。
新创建的执行对象有各自独立的ID,相同的PROC_INST_ID(关联原流程实例ID),表示同属一个流程实例。相同的PARENT_ID_,关联父节点所属执行对象ID。
3、汇聚网关中的某个执行对象执行完毕,执行对象仍存在于act_ru_execution中,直到所有出口结束并汇总至另一节点,所有新创建的执行对象完成,流程才进入下一步。
4、此时,查看act_hi_actinst表,可看到分支的并行网关只执行一次,但汇总的并行网关执行入度次数,分属不同的执行对象。
PS、并行网关不会解析连线条件,即使定义了判断条件,也会忽略,输出至所有出口。
5、并行网关的入度与出度不一定是平衡的,即分支网关的分支数目不一定等于汇聚网关的汇聚数目。(可一个分支在两个汇聚网关汇聚)
四、接受任务活动(ReceiveTask)
1、ReceiveTask不属于userTask(不存在于act_ru_task表),无法指定办理人(Assignee)。
2、当流程进行至ReceiveTask时会暂停,直到runtimeService接收到信号,才能进行下一步
由于实际业务中,外部表单通常只关联ProcessInstanceID,所以需通过流程实例ID以及receiveTask的Name来查询。
@Test
public void receiveTaskNext(){
String processInstanceId = "2501";
String act_id = "receiveTask1";//当前活动ID,必须为ReceiveTask,与.bpmn文件中task的Id关联,也即act_ru_execution中的ACT_ID
RuntimeService runtimeService = processEngine.getRuntimeService();
ExecutionQuery executionQuery = runtimeService.createExecutionQuery();//创建执行对象查询
/**查询出当前进行的执行对象*/
Execution execution = executionQuery.processInstanceId(processInstanceId)//找出当前流程实例
.activityId(act_id)//找出流程进行到的任务
.singleResult();
String executionID = execution.getId();
/** 使用流程变量,传递业务参数*/
runtimeService.setVariable(executionID, "变量名","变量值");
/** 将等待中的流程向后执行一步*/
runtimeService.signal(executionID);
}
PS、 UserTask任务需用taskService.complete()完成,而receiveTask任务才可用runtimeService.signal()推动。