Activiti的学习(六)——网关

网关用来控制流程的流向。

网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型。

Activiti的学习(六)——网关_第1张图片

一、排他网关(ExclusiveGateWay)

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

图形标记

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

XML内容

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

Activiti的学习(六)——网关_第2张图片

对应的XML内容如下:


  
        ${input == 1} 
	
    
        ${input == 2} 

  
        ${input == 3} 

说明:

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

设计流程图,使用排他网关

Activiti的学习(六)——网关_第3张图片

执行流程,由框架根据设置的流程变量选择执行其中的一个分支

/**
 * 排他网关测试
 */
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 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 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 map = task.getProcessVariables();
			Set> entrySet = map.entrySet();
			for (Entry entry : entrySet) {
				System.out.println(entry.getKey());
				System.out.println(entry.getValue());
			}
		}
	}
	
	/**
	 * 05-办理任务,设置流程变量
	 */
	@Test
	public void test5(){
		String taskId = "107504";
		Map variables = new HashMap();
		variables.put("money", 800);
		pe.getTaskService().complete(taskId, variables);
		System.out.println("办理任务完成....");
	}
}

二、并行网关(parallelGateWay)

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

图形标记

并行网关显示成一个普通网关(菱形)内部是一个“加号”图标, 表示“与(AND)”语义。

Activiti的学习(六)——网关_第4张图片

当两个任务都完成时,第二个并行网关会汇聚两个分支,因为它只有一条外出连线, 不会创建并行分支, 只会创建归档订单任务。

说明:

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

分支(fork) 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。

汇聚(join) 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

  1. 并行网关的进入和外出都是使用相同节点标示
  2. 如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
  3. 并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目相等)。如图中标示是合法的:

Activiti的学习(六)——网关_第5张图片

设计流程图,使用并行网关

Activiti的学习(六)——网关_第6张图片

测试并行网关

/**
 * 并行网关测试
 */
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 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 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 map = task.getProcessVariables();
			Set> entrySet = map.entrySet();
			for (Entry 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("办理任务完成....");
	}
}

 

你可能感兴趣的:(Activiti)