文章目录

1.网关概述

网关用来控制流程的流向。
网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型。
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_流程图

2.排他网关(ExclusiveGateWay)

排他网关(也叫异或(XOR)网关,或更技术性的叫法 基于数据的排他网关), 用来在流程中实现决策。

图形标记
排他网关显示成一个普通网关(比如,菱形图形), 内部是一个“X”图标,表示异或(XOR)语义。 注意,没有内部图标的网关,默认为排他网关。 BPMN 2.0规范不允许在同一个流程定义中同时使用没有X和有X的菱形图形。
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_流程图_02

XML内容
排他网关的XML内容是很直接的:用一行定义了网关, 条件表达式定义在外出顺序流中。 参考条件顺序流 获得这些表达式的可用配置。
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_启动流程_03

它对应的XML内容如下

<exclusiveGatewayid="exclusiveGw"name="Exclusive Gateway"/>
<sequenceFlowid="flow2"sourceRef="exclusiveGw"targetRef="theTask1">
<conditionExpressionxsi:type="tFormalExpression">${input == 1}</conditionExpression>
</sequenceFlow>
<sequenceFlowid="flow3"sourceRef="exclusiveGw"targetRef="theTask2">
<conditionExpressionxsi:type="tFormalExpression">${input == 2}</conditionExpression>
</sequenceFlow>
<sequenceFlowid="flow4"sourceRef="exclusiveGw"targetRef="theTask3">
<conditionExpressionxsi:type="tFormalExpression">${input == 3}</conditionExpression>
</sequenceFlow>

说明

1.一个排他网关对应一个以上的顺序流
2.由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
3.决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
4.如果没有任何一个出口符合条件则抛出异常。

第一步:设计流程图,使用排他网关
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_启动流程_04
第二步:执行流程,由框架根据设置的流程变量选择执行其中的一个分支

/**
* 排他网关测试
*/
public class ExclusiveGateWayTest {

ProcessEngine pe = null;

@Before
public void init() {
pe = ProcessEngines.getDefaultProcessEngine();
}

/**
* 01-部署流程定义
*/
@Test
public void test1() {
DeploymentBuilder deploymentBuilder = pe.getRepositoryService().createDeployment();
deploymentBuilder.addClasspathResource("com/activiti/ExclusiveGateWay/ExclusiveGateWay.bpmn");
deploymentBuilder.addClasspathResource("com/activiti/ExclusiveGateWay/ExclusiveGateWay.png");
Deployment deployment = deploymentBuilder.deploy();
System.out.println("流程定义部署成功...");
}


/**
* 02-查询流程定义列表
*/
@Test
public void test2() {
// 流程定义查询对象,用于查询表act_re_procdef
ProcessDefinitionQuery query = pe.getRepositoryService().createProcessDefinitionQuery();
// 添加排序条件
query.orderByProcessDefinitionVersion().desc();
// 添加分页查询
query.listPage(0, 10);
List<ProcessDefinition> list = query.list();
for (ProcessDefinition pd : list) {
System.out.println(pd.getId() + "--" + pd.getName() + "--key:" + pd.getKey());
}
}

/**
* 03-启动流程实例
*/
@Test
public void test3(){
String processDefinitionId = "ExclusiveGateWayTest:1:102504";
pe.getRuntimeService().startProcessInstanceById(processDefinitionId);
System.out.println("流程实例启动成功.....");
}

/**
* 04-查询个人任务列表
*/
@Test
public void test4() {
TaskQuery query = pe.getTaskService().createTaskQuery();
String assignee = "小B";
query.taskAssignee(assignee);
List<Task> list = query.list();
for (Task task : list) {
System.out.println("待办任务ID:"+task.getId());
System.out.println("待办任务名称:"+task.getName());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println("任务办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
Map<String, Object> map = task.getProcessVariables();
Set<Entry<String, Object>> entrySet = map.entrySet();
for (Entry<String, Object> entry : entrySet) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}

/**
* 05-办理任务,设置流程变量
*/
@Test
public void test5(){
String taskId = "107504";
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("money", 800);
pe.getTaskService().complete(taskId, variables);
System.out.println("办理任务完成....");
}
}

3.并行网关(parallelGateWay)

网关也可以表示流程中的并行情况。最简单的并行网关是parallelGateWay,它允许将流程 分成多条分支,也可以把多条分支 汇聚到一起。

图形标记
并行网关显示成一个普通网关(菱形)内部是一个“加号”图标, 表示“与(AND)”语义。
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_流程图_05
当两个任务都完成时,第二个并行网关会汇聚两个分支,因为它只有一条外出连线, 不会创建并行分支, 只会创建归档订单任务。
说明:

1.并行网关的功能是基于进入和外出的顺序流的:

分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

2.并行网关的进入和外出都是使用相同节点标示
3.如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
4.并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目相等)。如图中标示是合法的:
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_启动流程_06
第一步:设计流程图,使用并行网关
《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)_流程图_07
第二步:测试并行网关

/**
* 并行网关测试
*/
public class ParallelGateWayTest {

ProcessEngine pe = null;

@Before
public void init() {
pe = ProcessEngines.getDefaultProcessEngine();
}

/**
* 01-部署流程定义
*/
@Test
public void test1() {
DeploymentBuilder deploymentBuilder = pe.getRepositoryService().createDeployment();
deploymentBuilder.addClasspathResource("com/activiti/parallelGateWay/ParallelGateWay.bpmn");
deploymentBuilder.addClasspathResource("com/activiti/parallelGateWay/ParallelGateWay.png");
Deployment deployment = deploymentBuilder.deploy();
System.out.println("流程定义部署成功...");
}


/**
* 02-查询流程定义列表
*/
@Test
public void test2() {
// 流程定义查询对象,用于查询表act_re_procdef
ProcessDefinitionQuery query = pe.getRepositoryService().createProcessDefinitionQuery();
// 添加排序条件
query.orderByProcessDefinitionVersion().desc();
// 添加分页查询
query.listPage(0, 10);
List<ProcessDefinition> list = query.list();
for (ProcessDefinition pd : list) {
System.out.println(pd.getId() + "--" + pd.getName() + "--key:" + pd.getKey());
}
}

/**
* 03-启动流程实例
*/
@Test
public void test3(){
String processDefinitionId = "parallelGateWayTest:1:112504";
pe.getRuntimeService().startProcessInstanceById(processDefinitionId);
System.out.println("流程实例启动成功.....");
}

/**
* 04-查询个人任务列表
*/
@Test
public void test4() {
TaskQuery query = pe.getTaskService().createTaskQuery();
String assignee = "卖家A";
query.taskAssignee(assignee);
List<Task> list = query.list();
for (Task task : list) {
System.out.println("待办任务ID:"+task.getId());
System.out.println("待办任务名称:"+task.getName());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println("任务办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
Map<String, Object> map = task.getProcessVariables();
Set<Entry<String, Object>> entrySet = map.entrySet();
for (Entry<String, Object> entry : entrySet) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}

/**
* 05-办理任务
*/
@Test
public void test5(){
String taskId = "120002";
pe.getTaskService().complete(taskId);
System.out.println("办理任务完成....");
}
}