天天看點

《Activiti工作流架構》專題(八)-Activiti工作流架構-網關(gateWay)

文章目錄

  • ​​1.網關概述​​
  • ​​2.排他網關(ExclusiveGateWay)​​
  • ​​3.并行網關(parallelGateWay)​​

1.網關概述

網關用來控制流程的流向。

網關顯示成菱形圖形,内部有有一個小圖示。 圖示表示網關的類型。

《Activiti工作流架構》專題(八)-Activiti工作流架構-網關(gateWay)

2.排他網關(ExclusiveGateWay)

排他網關(也叫異或(XOR)網關,或更技術性的叫法 基于資料的排他網關), 用來在流程中實作決策。

 圖形标記

排他網關顯示成一個普通網關(比如,菱形圖形), 内部是一個“X”圖示,表示異或(XOR)語義。 注意,沒有内部圖示的網關,預設為排他網關。 BPMN 2.0規範不允許在同一個流程定義中同時使用沒有X和有X的菱形圖形。

《Activiti工作流架構》專題(八)-Activiti工作流架構-網關(gateWay)

 XML内容

排他網關的XML内容是很直接的:用一行定義了網關, 條件表達式定義在外出順序流中。 參考條件順序流 獲得這些表達式的可用配置。

《Activiti工作流架構》專題(八)-Activiti工作流架構-網關(gateWay)

 它對應的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)

第二步:執行流程,由架構根據設定的流程變量選擇執行其中的一個分支

/**
 * 排他網關測試
 */
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)

當兩個任務都完成時,第二個并行網關會彙聚兩個分支,因為它隻有一條外出連線, 不會建立并行分支, 隻會建立歸檔訂單任務。

說明:

分支(fork): 并行後的所有外出順序流,為每個順序流都建立一個并發分支。
彙聚(join): 所有到達并行網關,在此等待的進入分支, 直到所有進入順序流的分支都到達以後, 流程就會通過彙聚網關。      
/**
 * 并行網關測試
 */
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("辦理任務完成....");
  }
}