本人個人博客網站,歡迎訪問:學教府
一、概述
介紹: 在activiti中,事件按位置分可以有:開始事件、中間事件、邊界時間、結束事件;按事件的特性區分有:捕獲事件和拋出事件。除了事件,還有各種事件定義,常用的有:定時器事件定義、錯誤事件定義、信號事件定義、消息事件定義 、取消事件定義、補償事件定義等。事件和事件定義可以進行組合,成爲特定的事件。
此刻: 本文主要講四種開始事件
- 無指定開始事件:不爲開始事件指定任何的觸發條件的事件。此處不介紹。
- 定時器開始事件:在開始事件中加入定時器事件定義。
- 消息開始事件:在開始事件中加入消息事件定義。
- 錯誤開始事件:錯誤開始事件只能使用在事件的子流程。
二、定時器開始事件
- 流程圖
- 流程xml
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="StartEvent"> <timerEventDefinition> <!--從每分鐘的0s開始,每隔5秒開始一次流程(生成一個流程實例)--> <timeCycle>0/5 * * * * ?</timeCycle> </timerEventDefinition> </startEvent> <userTask activiti:exclusive="true" id="UserTask" name="UserTask"/> <endEvent id="_4" name="EndEvent"/> <sequenceFlow id="_5" sourceRef="_2" targetRef="UserTask"/> <sequenceFlow id="_6" sourceRef="UserTask" targetRef="_4"/> </process>
- 編碼部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); //部署流程後,不用我們自己啓動流程實例,定時器的時間到了後會自動啓動流程實例 Deployment deployment = repositoryService.createDeployment().addClasspathResource("timer-start-event.bpmn").deploy(); long count = runtimeService.createProcessInstanceQuery().count(); System.out.println("sleep前的流程實例個數:" + count); // // //睡眠20s,5s運行一次,則會多4個流程實例 Thread.sleep(20 * 1000); count = runtimeService.createProcessInstanceQuery().count(); System.out.println("sleep後的流程實例個數:" + count); processEngine.close(); System.exit(0);
- 結果查看
- 個人遇到問題及猜測:在測試過程中遇到個數和時間不對。 定時開始事件設置的時間間隔爲1s,31s後流程實例增加個數爲3個,個人猜測:定時開始事件的流程實例啓動間隔強制大於等於10s若設置的小於10s,則使用10s;若設置的時間間隔大於10s,則以設置的爲準)
三、消息開始事件
- 流程圖
- 流程xml
<message id="msg" name="msgName"></message> <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="StartEvent"> <!--開始事件引用消息--> <messageEventDefinition messageRef="msg"></messageEventDefinition> </startEvent> <userTask activiti:exclusive="true" id="UserTask" name="UserTask"/> <endEvent id="_4" name="EndEvent"/> <sequenceFlow id="_5" sourceRef="_2" targetRef="UserTask"/> <sequenceFlow id="_6" sourceRef="UserTask" targetRef="_4"/> </process>
- 編碼部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); Deployment deployment = repositoryService.createDeployment().addClasspathResource("message-start-event.bpmn").deploy(); //通過消息啓動流程實例,在一個項目中的消息事件會存儲在表act_ru_event_subscr中, // 並且因爲流程實例依靠具體的消息來啓動,因此在該項目中的消息需要唯一。例:如果一個流程的消息name定義爲"msgName",第一次部署時act_ru_event_subscr // 表會存儲消息與部署的流程定義的關聯,之後再部署相同的消息時,不會再增加記錄,不會與消息綁定;即只有第一綁定消息的流程定義是有效的。 ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("msgName"); System.out.println("流程實例ID:" + processInstance.getId()); processEngine.close(); System.exit(0);
4.結果查看:
運行結果:流程實例ID:345012
表act_ru_event_subscr:
四、錯誤開始事件
介紹: 此處模擬流程爲,一個班級,班長清點人數,發現人數少了後,馬上去報告班主任。
- 流程圖
- 流程xml
<error id="errorId" errorCode="abc"></error> <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="StartEvent"/> <serviceTask activiti:exclusive="true" id="CountPeople" name="CountPeople" activiti:class="com.xjf.test.delegate.CountPeopleDelegate"/> <endEvent id="_4" name="EndEvent"/> <sequenceFlow id="_5" sourceRef="_2" targetRef="CountPeople"/> <sequenceFlow id="_6" sourceRef="CountPeople" targetRef="_4"/> <!--triggeredByEvent配置必須爲true,默認是false--> <subProcess activiti:exclusive="true" id="_7" name="SubProcess" triggeredByEvent="true"> <startEvent id="_8" name="StartEvent"> <errorEventDefinition errorRef="errorId"></errorEventDefinition> </startEvent> <serviceTask activiti:exclusive="true" id="Report" name="Report" activiti:class="com.xjf.test.delegate.ReportDelegate"/> <endEvent id="_10" name="EndEvent"/> <sequenceFlow id="_3" sourceRef="_8" targetRef="Report"/> <sequenceFlow id="_11" sourceRef="Report" targetRef="_10"/> </subProcess> </process>
- ServiceTask的兩個委託類
public class CountPeopleDelegate implements JavaDelegate { @Override public void execute(DelegateExecution delegateExecution) { System.out.println("清點人數,要拋出錯誤"); //拋出錯誤,子流程的錯誤開始事件會捕獲 throw new BpmnError("abc"); } } public class ReportDelegate implements JavaDelegate { @Override public void execute(DelegateExecution delegateExecution) { System.out.println("少人了,準備上報"); } }
- 編碼發佈
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); Deployment deployment = repositoryService.createDeployment().addClasspathResource("error-start-event.bpmn").deploy(); ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); //流程實例啓動後,會自動執行:主流程拋出錯誤,子流程捕獲到錯誤然後一直執行完 ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); System.out.println("流程實例id:" + processInstance.getId()); processEngine.close(); System.exit(0);
- 查看結果
五、總結
- 所有的開始事件都是捕獲事件,都需要具體的動作或事件來觸發。
- 錯誤開始事件不能獨立存在,必須是其他事件的子流程。
- 邊界事件:在BPMN2.0的事件分類中,邊界事件被劃分到中間事件中,BPMN2.0中將狹義的中間事件和邊界事件,統稱爲中間事件。可以單獨作爲流程元素存在於流程中的事件爲中間事件,而附屬於某個流程元素(如任務、子流程等)的事件爲邊界事件。