一、概述
介紹: 在我們獲取流程實例後,需要對流程進行推進,就是使執行流往前執行。本篇即介紹在不同情況下,流程自動推進的方法。主要是三種:
- ①ReceiveTask接收信號後往前執行;
- ②中間信號捕獲事件接收信號後往前執行;
- ③中間消息捕獲事件接收消息後往前執行。
二、ReceiveTask接收信號
- bpmn文件如下:
- 編碼如下:
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);
- 打印結果,具體數據庫可以自行查看。
三、中間信號捕獲事件
- bpmn如下:
- 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>
- 編碼如下:
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);
- 結果如下:
四、中間消息捕獲事件
- bpmn文件
- 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>
- 編碼如下:
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);
- 結果
五、總結
- bpmn文件中 中間信號捕獲事件 和 中間消息捕獲 事件使用的都是同一個控件,區別是一個使用的是信號定義,一個是消息定義。
- 在執行流的數據庫表act_ru_execution中,執行流往前執行後使用的是同一個執行流id,版本變了(跟上面的中間消息捕獲事件聯繫),具體情況還要繼續學習後才知道。
- 中間信號捕獲事件中發送信號使執行流繼續執行(可以不指定執行流id),而中間消息捕獲事件中發送消息必指定執行流id,由此得出:信號可以是廣播處理,消息是一對一的。