《Activiti工作流框架》专题(八)-Activiti工作流框架-网关(gateWay)

1.网关概述

网关用来控制流程的流向。
网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型。
在这里插入图片描述

2.排他网关(ExclusiveGateWay)

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

图形标记
排他网关显示成一个普通网关(比如,菱形图形), 内部是一个“X”图标,表示异或(XOR)语义。 注意,没有内部图标的网关,默认为排他网关。 BPMN 2.0规范不允许在同一个流程定义中同时使用没有X和有X的菱形图形。
在这里插入图片描述

XML内容
排他网关的XML内容是很直接的:用一行定义了网关, 条件表达式定义在外出顺序流中。 参考条件顺序流 获得这些表达式的可用配置。
在这里插入图片描述

它对应的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.如果没有任何一个出口符合条件则抛出异常。

第一步:设计流程图,使用排他网关
在这里插入图片描述
第二步:执行流程,由框架根据设置的流程变量选择执行其中的一个分支

/**
 * 排他网关测试
 */
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)”语义。
在这里插入图片描述
当两个任务都完成时,第二个并行网关会汇聚两个分支,因为它只有一条外出连线, 不会创建并行分支, 只会创建归档订单任务。
说明:

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

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

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

/**
 * 并行网关测试
 */
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("办理任务完成....");
	}
}

猜你喜欢

转载自blog.csdn.net/BruceLiu_code/article/details/113644039