activiti入門和流程的執行過程(附程式碼)
阿新 • • 發佈:2018-12-17
1.定義bpmn檔案,這個檔案裡是用來定義流程的
2.釋出流程
釋出流程,流程的key值相同的情況下每次釋出一次,這個流程在資料庫的版本會+1
3.檢視流程定義
列印的資訊
可以看到,我剛才定義的流程已經更新了,現在是版本2了
4.建立流程例項
這裡是使用key來建立一個流程
5.檢視任務
建立一個例項之後,開始執行流程。一個流程分為很多的節點,每個節點對於不同的人就是不同的任務,所以要執行流程就是從檢視自己的任務開始。
在流程定義時我們可以看到 ,start之後,第一個執行事件是提出申請,assignee設定的是 staff
所以查詢任務的時候,可以根據staff檢視任務
執行程式碼後,看到了任務相關資訊
在資料庫中我們可以看到相關資訊
6.辦理任務
這裡的taskId就是上一步查出來的任務id,將任務Id傳進taskService.complete的引數中,執行
執行完成後,資料庫表中的資訊也更新
因為此時流程例項已經走到下一步,此時這個例項的名字是請假審批而不是提出申請了。
然後執行taskId為25002的任務,走到最後一步任務,這個流程例項就完成了。
一定要注意在操作過程中,資料庫的變化,這樣才能更好更快的理解activiti框架
附程式碼:
pom.xml引入依賴
<!--- Activiti依賴匯入 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring</artifactId> <version>5.18.0</version> <exclusions> <exclusion> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> </exclusion> </exclusions> </dependency> <!--- Activiti依賴匯入 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring</artifactId> <version>5.18.0</version> <exclusions> <exclusion> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>5.18.0</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </exclusion> <exclusion> <artifactId>spring-beans</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>jackson-core-asl</artifactId> <groupId>org.codehaus.jackson</groupId> </exclusion> <exclusion> <artifactId>commons-lang3</artifactId> <groupId>org.apache.commons</groupId> </exclusion> <exclusion> <artifactId>mybatis</artifactId> <groupId>org.mybatis</groupId> </exclusion> </exclusions> </dependency>
注意這裡的<esclusion> 排除裡面相關的依賴
測試類的程式碼:
public class activitiTest { /** * 一條語句建立processEngine, 要求: * 1、配置檔案必須在classpath根目錄下 * 2、配置檔名必須為activiti-context.xml或activiti.cfg.xml * 3、工廠物件的id必須為processEngine */ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); HistoryService historyService = processEngine.getHistoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); RepositoryService repositoryService = processEngine.getRepositoryService(); TaskService taskService = processEngine.getTaskService(); /** 通過zipinputstream完成部署 * 注意:這個的話,需要將bpmn和png檔案進行壓縮成zip檔案,然後放在專案src目錄下即可(當然其他目錄也可以) */ @Test public void testDeployFromZipinputStream(){ InputStream in = this.getClass().getClassLoader().getResourceAsStream("shenqing.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); processEngine.getRepositoryService() .createDeployment() .addZipInputStream(zipInputStream) .deploy(); } /** * 建立ActivitiEngine 生成資料庫表 */ @Test public void createActivitiEngine(){ //取得ProcessEngineConfiguration物件 ProcessEngineConfiguration engineConfiguration=ProcessEngineConfiguration. createStandaloneProcessEngineConfiguration(); /**2. 通過載入 activiti.cfg.xml 獲取 流程引擎 和自動建立資料庫及表*/ // 設定建立表的策略 (當沒有表時,自動建立表) // = "false";//不會自動建立表,沒有表,則拋異常 // = "create-drop";//先刪除,再建立表 // = "true";//假如沒有表,則自動建立 engineConfiguration.setDatabaseSchemaUpdate("true"); //通過ProcessEngineConfiguration物件建立 ProcessEngine 物件 ProcessEngine processEngine = engineConfiguration.buildProcessEngine(); System.out.println("流程引擎建立成功!"); } /** * 檢視流程圖 * 根據deploymentId和name(在act_ge_bytearray資料表中) */ @Test public void testShowImage() throws Exception{ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); InputStream inputStream = processEngine.getRepositoryService() /** * deploymentID * 檔案的名稱和路徑 */ .getResourceAsStream("110003","activiti/weekReport.bpmn"); OutputStream outputStream3 = new FileOutputStream("e:/weekReport.png"); int b = -1 ; while ((b=inputStream.read())!=-1){ outputStream3.write(b); } inputStream.close(); outputStream3.close(); } /** * 根據pdid檢視圖片(在act_re_procdef資料表中) * @throws Exception */ @Test public void testShowImage2() throws Exception{ InputStream inputStream = processEngine.getRepositoryService() .getProcessDiagram("leaveProcess:13:120004"); OutputStream outputStream = new FileOutputStream("e:/leaveProcess.png"); int b = -1 ; while ((b=inputStream.read())!=-1){ outputStream.write(b); } inputStream.close(); outputStream.close(); } /** * 部署流程定義 */ @Test public void deploy() { //獲取倉庫服務 :管理流程定義 RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deploy = repositoryService.createDeployment()//建立一個部署的構建器 .addClasspathResource("activiti/weekReport.bpmn")//從類路徑中新增資源,一次只能新增一個資源 .name("週報審批流程")//設定部署的名稱 .category("直銷部")//設定部署的類別 .deploy(); System.out.println("部署的id"+deploy.getId()); System.out.println("部署的名稱"+deploy.getName()); } /** * 建立流程例項 */ @Test public void startProcessInstance(){ String leaveId = "007"; String staffId = "04643"; HashMap<String,Object> map=new HashMap<>(); map.put("staffId",staffId); // 啟動流程 String processInstanceKey = "weekReportProcess"; // 三個引數分別為(String processDefinitionKey, String businessKey, HashMap<String, Object> variables) ProcessInstance pi = processEngine.getRuntimeService() .startProcessInstanceByKey(processInstanceKey,leaveId,map); System.out.println("建立流程例項成功,流程例項id:"+pi.getId() + " 流程定義id:" + pi.getProcessDefinitionId()); //預設完成第一步申請人的申請步驟 Task task = processEngine.getTaskService() .createTaskQuery() .processInstanceId(pi.getId()) .singleResult(); String nextStaffId = "04646"; map.put("staffId",nextStaffId); processEngine.getTaskService() .complete(task.getId(),map); } /** * 查詢所有的正在執行的任務 */ @Test public void testQueryTask(){ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); List<Task> tasks = processEngine.getTaskService() .createTaskQuery() .list(); for (Task task : tasks) { System.out.println(task.getName()); } } /** * 根據piid得到當前正在執行的流程例項的正在活動的節點 */ @Test public void testActivity(){ ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); /** * 根據piid得到流程例項 */ ProcessInstance pi = processEngine.getRuntimeService() .createProcessInstanceQuery() .processInstanceId("127501") .singleResult(); String activityId = pi.getActivityId();//當前流程例項正在執行的activityId System.out.println(activityId); } /** * 查找個人任務 */ @Test public void getMyTaskInfo() { String staffId = "007"; List<Task> listTask = processEngine.getTaskService() .createTaskQuery() .taskAssignee(staffId) .list(); if (listTask != null && listTask.size() > 0) { for (Task task : listTask) { System.out.println("任務ID:"+task.getId()); System.out.println("任務名稱:"+task.getName()); System.out.println("任務時間:"+task.getCreateTime()); System.out.println("任務的辦理人:"+task.getAssignee()); System.out.println("任務的例項ID:"+task.getProcessDefinitionId()); System.out.println("#########################################"); } } } /** * 執行任務 * @return */ @Test public void completeMyPersonTask() { String taskId = "170002"; String nextStaffId = "02222"; HashMap<String,Object> map=new HashMap<>(); map.put("staffId",nextStaffId); processEngine.getTaskService() .complete(taskId,map); System.out.println("檢視當前任務成功"+"完成任務,任務ID:" + taskId); } /** * 終止流程例項 * @return */ @Test public void deleteProcessInstance() { String taskId = "135002"; String reason = "太少了,100個新增!"; Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(task.getProcessInstanceId()).singleResult(); processEngine.getRuntimeService() .deleteProcessInstance(processInstance.getId(),reason); System.out.println("停止taskId為:" + taskId+"的任務"); } /** * 查詢執行物件表,使用流程例項ID和當前活動的名稱(receivetask1) */ @Test public void queryExecution(){ ProcessInstance pi = processEngine.getRuntimeService() .createProcessInstanceQuery() .processDefinitionKey("weekReportProcess") .singleResult(); //3.查詢執行物件表,使用流程例項ID和當前活動的名稱(receivetask1) String processInstanceId = pi.getId();//得到流程例項ID Execution execution1 = processEngine.getRuntimeService() .createExecutionQuery() .processInstanceId(processInstanceId)//流程例項ID // .activityId("receivetask1")//當前活動的名稱 .singleResult(); //5.向後執行一步 processEngine.getRuntimeService() .signal(execution1.getId()); } /** * 直接跳過某一個執行步驟 * @return */ @Test public void passTask() { String executionId = "127501"; processEngine.getRuntimeService().signal(executionId); System.out.println("直接執行下一步"); } /** * 直接完成執行者為空的步驟,直到有執行者的那一步並設定執行者id */ @Test public void passNull(){ TaskService taskService = processEngine.getTaskService(); //上一個任務的執行者 String assignee = "04646"; //當前流程例項Id String processInstanceId = "165001"; //整個流程中,所有節點涉及的執行人全部加入到一個數組中 ArrayList<String> assignees= new ArrayList<>(); assignees.add("04643"); assignees.add("04646"); assignees.add(""); assignees.add("007"); //獲得上一個執行者後面的陣列 List<String> subAssigneeList = assignees.subList(assignees.indexOf(assignee)+1, assignees.size()); //遍歷陣列 查詢下一個執行者是否為空 //如果為空就預設完成進入下一步,直到第一個不為空的執行者 跳出foreach for (String l:subAssigneeList ) { System.out.println("subList的位置"+subAssigneeList.indexOf(l)+"元素是:"+l); //如果 下一個任務的執行人為空,直接預設完成這一步,並根據陣列將下一個執行人加入下一個任務中 if (l.equals(null) || l.length() == 0){ Task task = taskService.createTaskQuery() .processInstanceId(processInstanceId) .singleResult(); HashMap<String, Object> var = new HashMap<>(); var.put("staffId",subAssigneeList.get( subAssigneeList.indexOf(l) + 1)); taskService.complete(task.getId(),var); System.out.println("這個位置的執行者是空,直接預設完成這一步"); }else { System.out.println("存在執行者,跳出此迴圈"); break; } } System.out.println(subAssigneeList); } @Test public void queryProcessInstanceHistory(){ List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery() .orderByHistoricActivityInstanceEndTime() .desc() .processInstanceId("132501") .list(); for (HistoricActivityInstance h:list){ System.out.println(h.getId()); System.out.println(h.getActivityId()); System.out.println(h.getAssignee()); System.out.println(h.getExecutionId()); System.out.println(h.getProcessInstanceId()); System.out.println("##############################"); } } }
activiti.cfg.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:sqlserver://xxxDatabaseName=activititest" />
<property name="jdbcDriver" value="" />
<property name="jdbcUsername" value="" />
<property name="jdbcPassword" value="" />
<!-- 建表策略 -->
<!--
"false";不能自動建立表,需要表存在
"create-drop";先刪除表再建立表
"true";如果表不存在,自動建立表
-->
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
spring配置檔案裡可以這麼配置
<!-- 配置activiti -->
<context:component-scan base-package="com.wolwo.activiti">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>
<!-- 配置流程引擎檔案 -->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="labelFontName" value="宋體"/>
<property name="activityFontName" value="宋體" />
<!-- 是否自動建立23張表 -->
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="deploymentResources" value="activiti/**/*.bpmn"/>
</bean>
<!-- 配置建立流程引擎物件 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />