本人个人博客网站,欢迎访问:学教府
一、概述
介绍: 在我们获取流程实例后,需要对流程进行推进,就是使执行流往前执行。本篇即介绍在不同情况下,流程自动推进的方法。主要是三种:
- ①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,由此得出:信号可以是广播处理,消息是一对一的。