第九節:Activiti6.0——ReceiveTask接收信號、中間信號捕獲事件和中間消息捕獲事件的流程推進

一、概述

介紹: 在我們獲取流程實例後,需要對流程進行推進,就是使執行流往前執行。本篇即介紹在不同情況下,流程自動推進的方法。主要是三種:

  • ①ReceiveTask接收信號後往前執行
  • ②中間信號捕獲事件接收信號後往前執行
  • ③中間消息捕獲事件接收消息後往前執行

二、ReceiveTask接收信號

  1. bpmn文件如下:
    receiveTask的bpmn
  2. 編碼如下:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();

Deployment deployment = repositoryService.createDeployment().addClasspathResource("receiveTask.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

//獲取流程實例id,即爲主執行流的id
System.out.println("流程實例id:" + processInstance.getId());

//獲取執行流
Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();

//使用ACT_ID_來標識執行流,對應bpmn文件中receiveTask標籤的id
System.out.println("當前執行流:" + execution.getActivityId());

Thread.sleep(10000);

//調用方法使流程繼續,需要執行流的id來進行觸發(此處bpmn使用的是ReceiveTask來接收觸發,經測試UserTask不能)
runtimeService.trigger(execution.getId());

//再次查詢當前執行流
execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();

//使用ACT_ID_來標識執行流
System.out.println("當前執行流:" + execution.getActivityId());

//關閉
processEngine.close();
System.exit(0);
  1. 打印結果,具體數據庫可以自行查看。
    執行結果

三、中間信號捕獲事件

  1. bpmn如下:
    中間信號捕獲事件bpmn
  2. xml需要添加信號定義,才能在發送該信號後,事件能捕獲到。
<!--信號定義-->
<signal id="testSignal" name="testSignal2"></signal>
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
  <startEvent id="_2" name="StartEvent"/>
  <intermediateCatchEvent id="IntermediateCatchingEvent" name="IntermediateCatchingEvent" >
    <!--信號定義引用-->
    <signalEventDefinition signalRef="testSignal" ></signalEventDefinition>
  </intermediateCatchEvent>
  <userTask activiti:exclusive="true" id="UserTask" name="UserTask"/>
  <endEvent id="_5" name="EndEvent"/>
  <sequenceFlow id="_6" sourceRef="_2" targetRef="IntermediateCatchingEvent"/>
  <sequenceFlow id="_7" sourceRef="IntermediateCatchingEvent" targetRef="UserTask"/>
  <sequenceFlow id="_8" sourceRef="UserTask" targetRef="_5"/>
</process>
  1. 編碼如下:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();

Deployment deployment = repositoryService.createDeployment().addClasspathResource("SingleEvent.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
System.out.println("主執行流id: " + processInstance.getId());

//獲取當前執行流,此處知道子執行流是一個,所以使用的是singleResult,如果是多個則需要用list
Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();
System.out.println("當前執行流:" + execution.getActivityId());

//發送信號使執行流繼續執行(可以不指定執行流id),經測試:此處的信號名稱與bpmn文件中信號定義的name值相同纔行
runtimeService.signalEventReceived("testSignal2");
//        runtimeService.signalEventReceived("testSignal2",execution.getId());

//獲取當前子執行流
execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();
System.out.println("當前執行流:" + execution.getActivityId());

processEngine.close();
System.exit(0);
  1. 結果如下:
    結果

四、中間消息捕獲事件

  1. bpmn文件
    中間消息捕獲事件
  2. xml需要添加消息定義,這樣才能在發送消息後能進行捕獲
<!--消息定義-->
<message id="messageId" name="messageName"></message>
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
  <startEvent id="_2" name="StartEvent"/>
  <intermediateCatchEvent id="IntermediateCatchingEvent" name="IntermediateCatchingEvent">
    <!--消息定義引用-->
    <messageEventDefinition messageRef="messageId"></messageEventDefinition>
  </intermediateCatchEvent>
  <userTask activiti:exclusive="true" id="UserTask" name="UserTask"/>
  <endEvent id="_5" name="EndEvent"/>
  <sequenceFlow id="_6" sourceRef="_2" targetRef="IntermediateCatchingEvent"/>
  <sequenceFlow id="_7" sourceRef="IntermediateCatchingEvent" targetRef="UserTask"/>
  <sequenceFlow id="_8" sourceRef="UserTask" targetRef="_5"/>
</process>
  1. 編碼如下:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();

Deployment deployment = repositoryService.createDeployment().addClasspathResource("MessageEvent.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

System.out.println("主執行流id: " + processInstance.getId());

//使用任務的方法去獲取執行流,居然獲取不到,報空指針
//        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
//        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();

//獲取當前執行流,此處知道子執行流是一個,所以使用的是singleResult,如果是多個則需要用list
Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();
System.out.println("當前執行流id:" + execution.getId() + "               執行流名稱:" + execution.getActivityId());

//發送消息,使執行流繼續執行,發送的消息名稱也是對應bpmn文件消息定義中的name標籤值,
//消息中間事件和信號中間事件的區別:信號可以不指定執行流id,消息必須執行執行流id。就相當於信號可以是廣播處理,消息是一對一的。
runtimeService.messageEventReceived("messageName",execution.getId());

//獲取當前執行流
execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().singleResult();
System.out.println("當前執行流id:" + execution.getId() + "               執行流名稱:" + execution.getActivityId());

processEngine.close();
System.exit(0);
  1. 結果
    結果

五、總結

  1. bpmn文件中 中間信號捕獲事件中間消息捕獲 事件使用的都是同一個控件,區別是一個使用的是信號定義,一個是消息定義。
  2. 在執行流的數據庫表act_ru_execution中,執行流往前執行後使用的是同一個執行流id,版本變了(跟上面的中間消息捕獲事件聯繫),具體情況還要繼續學習後才知道。
    在這裏插入圖片描述
  3. 中間信號捕獲事件中發送信號使執行流繼續執行(可以不指定執行流id),而中間消息捕獲事件中發送消息必指定執行流id,由此得出:信號可以是廣播處理,消息是一對一的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章