Activiti入門學習demo
本文提供activiti入門學習的demo,包括流程文件和調用代碼。
一、新建工程,導入相應的jar包,建議用maven做jar包的依賴管理。maven依賴部分代碼如下:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--activiti的核心jar包,其相關依賴jar包會一并導入--> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>5.18.0</version> </dependency> <!--h2內存數據庫的jar包,本文的例子用的是h2數據庫,基于內存模式,方便測試--> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.176</version> </dependency> </dependencies>
二、流程文件,測試中用到的兩個流程文件,放到合適的目錄下,一般是resources目錄下,至于如何生成流程文件,請參照相關資料:
-
MyProcess.bpmn20.xml
</li> </ol><?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="myProcess" name="My process" isExecutable="true"> <startEvent id="startevent1" name="Start"></startEvent> <userTask id="usertask1" name="User Task"></userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> </process> </definitions>
這是一個最簡單的流程,流程圖如下:
2. pool.bpmn
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <collaboration id="Collaboration"> <participant id="pool1" name="請假流程" processRef="process_pool1"></participant> </collaboration> <process id="process_pool1" name="process_pool1" isExecutable="true"> <laneSet id="laneSet_process_pool1"> <lane id="lane1" name="員工"> <flowNodeRef>startevent1</flowNodeRef> <flowNodeRef>usertask1</flowNodeRef> <flowNodeRef>usertask4</flowNodeRef> <flowNodeRef>endevent1</flowNodeRef> <flowNodeRef>exclusivegateway3</flowNodeRef> </lane> <lane id="lane2" name="領導"> <flowNodeRef>usertask2</flowNodeRef> <flowNodeRef>exclusivegateway1</flowNodeRef> </lane> <lane id="lane3" name="人事"> <flowNodeRef>usertask3</flowNodeRef> <flowNodeRef>exclusivegateway2</flowNodeRef> </lane> </laneSet> <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"> <extensionElements> <activiti:formProperty id="startDate" name="請假開始日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> <activiti:formProperty id="endDate" name="請假結束日期" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> <activiti:formProperty id="reason" name="請假原因" type="string" required="true"></activiti:formProperty> </extensionElements> </startEvent> <userTask id="usertask1" name="調整申請" activiti:assignee="${applyUserId}"> <extensionElements> <activiti:formProperty id="startDate" name="請假開始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> <activiti:formProperty id="endDate" name="請假結束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> <activiti:formProperty id="reason" name="請假原因" type="string" value="${reason}" required="true"></activiti:formProperty> <activiti:formProperty id="reApply" name="重新申請" type="enum" required="true"> <activiti:value id="true" name="重新申請"></activiti:value> <activiti:value id="false" name="取消申請"></activiti:value> </activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow2" name="提交申請" sourceRef="startevent1" targetRef="usertask2"></sequenceFlow> <userTask id="usertask2" name="領導審批" activiti:candidateGroups="deptLeader"> <extensionElements> <activiti:formProperty id="startDate" name="請假開始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="endDate" name="請假結束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="reason" name="請假原因" type="string" value="${reason}" writable="false"></activiti:formProperty> <activiti:formProperty id="deptLeaderApprove" name="審批意見" type="enum" required="true"> <activiti:value id="true" name="同意"></activiti:value> <activiti:value id="false" name="拒絕"></activiti:value> </activiti:formProperty> </extensionElements> </userTask> <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway> <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="exclusivegateway1"></sequenceFlow> <sequenceFlow id="flow4" name="同意" sourceRef="exclusivegateway1" targetRef="usertask3"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApprove=='true'}]]></conditionExpression> </sequenceFlow> <userTask id="usertask3" name="人事審批" activiti:candidateGroups="hr"> <extensionElements> <activiti:formProperty id="startDate" name="請假開始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="endDate" name="請假結束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="reason" name="請假原因" type="string" value="${reason}" writable="false"></activiti:formProperty> <activiti:formProperty id="hrApprove" name="審批意見" type="enum" required="true"> <activiti:value id="true" name="同意"></activiti:value> <activiti:value id="false" name="拒絕"></activiti:value> </activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow6" name="不同意" sourceRef="exclusivegateway1" targetRef="usertask1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApprove=='false'}]]></conditionExpression> </sequenceFlow> <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> <sequenceFlow id="flow7" sourceRef="usertask3" targetRef="exclusivegateway2"></sequenceFlow> <sequenceFlow id="flow8" name="同意" sourceRef="exclusivegateway2" targetRef="usertask4"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove=='true'}]]></conditionExpression> </sequenceFlow> <userTask id="usertask4" name="銷假" activiti:assignee="${applyUserId}"> <extensionElements> <activiti:formProperty id="startDate" name="請假開始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="endDate" name="請假結束日期" type="date" value="${endDate}" datePattern="yyyy-MM-dd" writable="false"></activiti:formProperty> <activiti:formProperty id="reason" name="請假原因" type="string" value="${reason}" writable="false"></activiti:formProperty> <activiti:formProperty id="reportBackDate" name="銷假日期" type="date" default="${endDate}" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow9" name="不同意" sourceRef="exclusivegateway2" targetRef="usertask1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove=='false'}]]></conditionExpression> </sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow10" sourceRef="usertask4" targetRef="endevent1"> <extensionElements> <activiti:executionListener event="take" expression="${execution.setVariable('result','OK')}"></activiti:executionListener> </extensionElements> </sequenceFlow> <sequenceFlow id="flow11" name="繼續提交申請" sourceRef="exclusivegateway3" targetRef="usertask2"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply=='true'}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow12" name="取消申請" sourceRef="exclusivegateway3" targetRef="endevent1"> <extensionElements> <activiti:executionListener event="take" expression="${execution.setVariable('result','canceled')}"></activiti:executionListener> </extensionElements> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply=='false'}]]></conditionExpression> </sequenceFlow> <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway> <sequenceFlow id="flow13" sourceRef="usertask1" targetRef="exclusivegateway3"></sequenceFlow> </process> </definitions>
這是一個請假流程,流程圖如下:
三、用于測試的java代碼,采用junit方式運行:
package com.wangtl.activiti; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import org.activiti.engine.FormService; import org.activiti.engine.HistoryService; import org.activiti.engine.IdentityService; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.history.HistoricDetail; import org.activiti.engine.history.HistoricFormProperty; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.history.HistoricVariableInstance; import org.activiti.engine.history.HistoricVariableUpdate; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.junit.Test; public class VerySimpleLeaveProcessTest { @Test public void testProcessDefinition() throws Exception{ // 創建 Activiti流程引擎 ProcessEngine processEngine= ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); // 取得 Activiti 服務 RepositoryService repositoryService=processEngine.getRepositoryService(); // 部署流程定義 Deployment deploy=repositoryService.createDeployment().addClasspathResource("MyProcess.bpmn20.xml").deploy(); ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()) .singleResult(); System.out.println(processDefinition.getKey()); // 啟動流程實例 RuntimeService runtimeService=processEngine.getRuntimeService(); ProcessInstance processInstance=runtimeService.startProcessInstanceByKey(processDefinition.getKey()); System.out.println("pid="+processInstance.getId()+",pdid="+ processInstance.getProcessDefinitionId()); } @Test public void testStartProcess() throws Exception{ // 1.創建 Activiti流程引擎(此處使用的是h2數據庫,并啟用的是內存模式,即數據保存在內存中,程序運行完數據就丟失) ProcessEngine processEngine= ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); // 2.部署流程定義 //取得 Activiti 服務 RepositoryService repositoryService=processEngine.getRepositoryService(); //獲得流程定義的相關數據 String fileName="E:/workspace/activiti-demo/src/main/resources/MyProcess.bpmn20.xml"; File f =new File(fileName); InputStream fileInputStream = new FileInputStream(f); //創建Deployment,同時部署流程定義 repositoryService.createDeployment() .addInputStream(fileName, fileInputStream) .deploy(); //查看定義的流程(非必須,只是驗證流程定義是否部署成功) ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery() .singleResult(); System.out.println("流程定義文件的key為:"+processDefinition.getKey()); // 3.啟動流程實例 RuntimeService runtimeService=processEngine.getRuntimeService(); ProcessInstance processInstance=runtimeService.startProcessInstanceByKey(processDefinition.getKey()); System.out.println("流程實例的id="+processInstance.getId()+",流程實例的definitionId="+ processInstance.getProcessDefinitionId()); //4.取得當前任務 //獲得任務服務 TaskService taskService=processEngine.getTaskService(); //取得當前任務(由于流程定義中沒有指明任務指派給誰,所以這里不用申明任務由誰獲得) Task task=taskService.createTaskQuery().singleResult(); System.out.println("當前任務的名稱是:"+task.getName()); //5.認領任務(由于流程定義中沒有指明任務指派給誰,任何人都可以認領該任務,如這里的“leaderUser”) taskService.claim(task.getId(), "leaderUser"); //查看"leaderUser"現在是否能夠獲取到該任務(非必須) task=taskService.createTaskQuery().taskAssignee("leaderUser").singleResult(); System.out.println("認領任務的人是:"+task.getAssignee()); //6.完成任務 taskService.complete(task.getId()); //以下是驗證任務是否完成,通過重新查找任務(為空),查詢歷史記錄(有),說明之前的任務完成了(非必須) task=taskService.createTaskQuery().singleResult(); System.out.println("當前的任務是:"+task); HistoryService historyService=processEngine.getHistoryService(); long count=historyService.createHistoricProcessInstanceQuery().finished().count(); System.out.println("已完成的任務數是:"+count); } @Test public void testStartProcess2() throws Exception{ // 1.創建 Activiti流程引擎(此處使用的是h2數據庫,并啟用的是內存模式,即數據保存在內存中,程序運行完數據就丟失) ProcessEngine processEngine= ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration() // .setHistory("full") .buildProcessEngine(); // 2.部署流程定義 //取得 Activiti 服務 RepositoryService repositoryService=processEngine.getRepositoryService(); //獲得流程定義的相關數據 String fileName="E:/workspace/activiti-demo/src/main/resources/pool.bpmn"; File f =new File(fileName); InputStream fileInputStream = new FileInputStream(f); //創建Deployment,同時部署流程定義 repositoryService.createDeployment() .addInputStream(fileName, fileInputStream) .deploy(); //查看定義的流程(非必須,只是驗證流程定義是否部署成功) ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery() .processDefinitionKey("process_pool1") .singleResult(); System.out.println("流程定義文件的key為:"+processDefinition.getKey()); //設置當前用戶 String currentUserId="hen"; IdentityService identityService=processEngine.getIdentityService(); identityService.setAuthenticatedUserId(currentUserId); //設置表單變量 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Map<String,String> variables =new HashMap<String,String>(); Calendar ca=Calendar.getInstance(); String startDate = sdf.format(ca.getTime()); ca.add(Calendar.DAY_OF_MONTH, 2); String endDate=sdf.format(ca.getTime()); variables.put("startDate", startDate); variables.put("endDate", endDate); variables.put("reason", "年假"); // 3.當前用戶啟動流程實例(類似RuntimeService,只是這里帶上了表單數據) FormService formService=processEngine.getFormService(); ProcessInstance processInstance= formService.submitStartFormData(processDefinition.getId(), variables); System.out.println("流程實例的id="+processInstance.getId()+",流程實例的definitionId="+ processInstance.getProcessDefinitionId()); //取得deptLeader的任務 TaskService taskService=processEngine.getTaskService(); Task leaderTask=taskService.createTaskQuery().taskCandidateGroup("deptLeader").singleResult(); System.out.println("當前任務的名稱是:"+leaderTask.getName()); //審批當前任務(類似于TaskService的complete) variables=new HashMap<String,String>(); variables.put("deptLeaderApprove", "true"); formService.submitTaskFormData(leaderTask.getId(), variables); //取得hr的任務 Task hrTask=taskService.createTaskQuery().taskCandidateGroup("hr").singleResult(); System.out.println("當前任務的名稱是:"+hrTask.getName()); //審批當前任務(類似于TaskService的complete) variables=new HashMap<String,String>(); variables.put("hrApprove", "true"); formService.submitTaskFormData(hrTask.getId(), variables); //取得用戶的銷假任務 Task reportBackTask=taskService.createTaskQuery().taskAssignee(currentUserId).singleResult(); //提交任務 variables=new HashMap<String,String>(); variables.put("reportBackDate", endDate); formService.submitTaskFormData(reportBackTask.getId(),variables); //以下是驗證流程是否結束(非必須) HistoryService historyService=processEngine.getHistoryService(); HistoricProcessInstance historicProcessInstance=historyService .createHistoricProcessInstanceQuery().finished().singleResult(); System.out.println("已執行的流程id:"+historicProcessInstance.getId()); Map<String,Object> historyVariables=packageVariables(historyService,processInstance); System.out.println(historyVariables.get("result")); } private Map<String,Object> packageVariables(HistoryService historyService,ProcessInstance processInstance){ Map<String,Object> historyVariables=new HashMap<String,Object>(); //在保存表單字段的同時會復制一份經過類型轉換的值,并以字段的ID為變量名保存到數據庫中,當然前提是要設置引擎的“history”屬性為“full”級別 /List<HistoricDetail> list= historyService.createHistoricDetailQuery().processInstanceId(processInstance.getId()).list(); System.out.println("歷史記錄數"+list.size()); for(HistoricDetail historicDetail:list){ if(historicDetail instanceof HistoricFormProperty){ HistoricFormProperty field=(HistoricFormProperty) historicDetail; historyVariables.put(field.getPropertyId(), field.getPropertyValue()); System.out.println("form field: taskId="+field.getTaskId()+", " +field.getPropertyId()+"="+field.getPropertyValue()); }else if(historicDetail instanceof HistoricVariableUpdate){ HistoricVariableUpdate variable=(HistoricVariableUpdate) historicDetail; historyVariables.put(variable.getVariableName(),variable.getValue()); System.out.println("variable: "+variable.getVariableName()+"="+variable.getValue()); } }/ / 查詢所有保存的變量:5.11版本之后,從表act_hi_varinst/ List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).list(); for (HistoricVariableInstance variable : list) { historyVariables.put(variable.getVariableName(),variable.getValue()); System.out.println("variable: " + variable.getVariableName() + " = " + variable.getValue()); } / 只讀取表單變量:從表act_hi_detail/ /List<HistoricDetail> formProperties = historyService.createHistoricDetailQuery().processInstanceId(processInstance.getId()) .formProperties().list(); for (HistoricDetail historicDetail : formProperties) { HistoricFormProperty field = (HistoricFormProperty) historicDetail; historyVariables.put(field.getPropertyId(), field.getPropertyValue()); System.out.println("field id: " + field.getPropertyId() + ", value: " + field.getPropertyValue()); } /
return historyVariables; } }</pre>來自:http://my.oschina.net/wangrikui/blog/506338
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!