一、什么是流程定義
流程定義是線下bpmn2.0標椎去描述業務流程,通常使用activiti-explorer(web控制台)或 activiti-eclipse-designer 插件對業務流程進行建模,這兩種方式都遵循 bpmn2.0 標准。使用designer 設計器繪制流程,會生成兩個文件:.bpmn 和.png
1、.bpmn文件
2、.png文件生成
①首先將.bpmn文件改為.xml文件
②然后右鍵該xml文件Diagrams--->show BPMN 2.0 Designer就能生成一張流程圖,將流程圖導出保存到項目對應目錄即可
③然后將.xml改回.bpmn即可
注意:
流程圖生成前須設置編碼格式然后重啟IDEA!!!
-Dfile.encoding=UTF-8
二、流程定義部署
1、什么是流程定義部署
將線下定義的流程部署到activiti數據庫中,這就是流程定義部署,通過調用activiti的api將流程定義的bpmn和png兩個文件一個一個添加部署到activiti中,也可以將兩個文件打成ZIP包進行部署;
2、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" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/contex http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--數據源--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/activiti"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean> <!--配置Activiti使用的processEngine對象 默認命名為processEngineConfiguration--> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!--注入數據源--> <property name="dataSource" ref="dataSource"/> <!--配置數據源方式二:--> <!--<property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>--> <!--指定數據庫生成策略--> <property name="databaseSchemaUpdate" value="true"/> </bean> </beans>
3、單個文件部署方式
分別將bpmn文件和png圖片文件部署;
package com.zn; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.junit.Test; public class ActivitiTest { /*流程部署 * `act_ge_bytearray` 流程定義的資源信息,包含bpmn和png流程文件信息 * `act_re_deployment` 流程部署信息 包含流程名稱,ID,key等 * `act_re_procdef` 流程定義信息 * */ @Test public void deployment(){ //獲取ProcessEngine對象 默認配置文件名稱:activiti.cfg.xml 並且configuration的Bean實例ID為processEngineConfiguration ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取RepositoryService對象進行流程部署 RepositoryService repositoryService = processEngine.getRepositoryService(); //進行部署,將對應的流程定義文件生成到數據庫當中,作為記錄進行保存 Deployment deployment = repositoryService.createDeployment() //加載流程文件 .addClasspathResource("bpmnFiles/holiday.bpmn") .addClasspathResource("bpmnFiles/holiday.png") //設置流程名稱 .name("請假流程") .key("holidayKey") //部署 .deploy(); //輸出部署信息 System.out.println("流程名稱:"+deployment.getName()); System.out.println("流程ID:"+deployment.getId()); System.out.println("流程Key:"+deployment.getKey()); } }
4、壓縮包部署方式
將bpmn文件和png圖片壓縮成zip包;
package com.zn; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.junit.Test; import java.io.InputStream; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 壓縮包的方式部署流程 */ @Test public void deploymentByZip(){ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取一個RepositoryService對象 RepositoryService repositoryService = processEngine.getRepositoryService(); //定義一個輸入流,加載Zip文件 InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("bpmnFiles/holiday.zip"); //定義一個ZIPInputStream對象 ZipInputStream zipInputStream=new ZipInputStream(inputStream); //流程部署 Deployment deploy = repositoryService.createDeployment() .addZipInputStream(zipInputStream) .name("請求審批流程") .key("holidayKey") .deploy(); System.out.println("流程名稱:"+deploy.getName()); } }
執行操作控制台效果
數據庫展示
5、流程定義查詢
查詢部署的流程定義;
package com.zn; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.junit.Test; import java.io.InputStream; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 流程定義信息查看 */ @Test public void getDefaultProcessEngine(){ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取一個RepositoryService對象 RepositoryService repositoryService = processEngine.getRepositoryService(); //得到流程定義查看對象ProcessDefinitionQuery ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); //指定查看的流程processDefinitionKey()指定流程定義的key值 orderByProcessDefinitionVersion根據流程定義版本號排序 List<ProcessDefinition> holiday = processDefinitionQuery.processDefinitionKey("holiday").orderByProcessDefinitionVersion().desc().list(); for (ProcessDefinition processDefinition:holiday) { System.out.println("流程定義ID:"+processDefinition.getId()); System.out.println("流程定義的名稱:"+processDefinition.getName()); System.out.println("流程定義的Key:"+processDefinition.getKey()); System.out.println("流程定義的版本號:"+processDefinition.getVersion()); } } }
執行操作控制台效果
6、流程定義刪除
刪除已經部署成功的流程定義;
package com.zn; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.junit.Test; import java.io.InputStream; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 刪除流程: * 假設在刪除時,當前正在有該流程實例執行,那么會導致刪除失敗 * 如果強制要求,則可以使用repositoryService.deleteDeployment("1",true); true代表級聯刪除 */ @Test public void deleteDeployment(){ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取一個RepositoryService對象 RepositoryService repositoryService = processEngine.getRepositoryService(); //刪除流程 repositoryService.deleteDeployment("10001",true); } }
說明:
1.使用RepositoryService刪除流程定義;
2.如果流程定義下沒有正在運行的流程,則可以普通刪除;
3.如果將流程定義下存在已經運行的流程,使用普通刪除報錯,可用級聯刪除方法將流程及相關級聯全部刪除;
三、從數據庫中讀取資源文件到本地
1、導入依賴
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
2、代碼實現
package com.zn; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.apache.commons.io.IOUtils; import org.junit.Test; import java.io.*; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 從數據中讀取資源文件到本地 */ @Test public void getResource() throws IOException { //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取一個RepositoryService對象 RepositoryService repositoryService = processEngine.getRepositoryService(); //獲取到流程查詢對象 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); //獲取到流程資源 processDefinitionQuery.processDefinitionKey("holiday"); //獲取單一結果 ProcessDefinition processDefinition = processDefinitionQuery.singleResult(); //流程部署的ID String deploymentId = processDefinition.getDeploymentId(); //獲取到bpmnResource InputStream bpmnStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName()); //獲取到png InputStream pngStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName()); //構建輸出流 OutputStream bpmnOut = new FileOutputStream("E:\\accp\\Y2\\畢設項目\\"+processDefinition.getResourceName()); OutputStream pngOut = new FileOutputStream("E:\\accp\\Y2\\畢設項目\\"+processDefinition.getDiagramResourceName()); //將數據輸出到磁盤當中 IOUtils.copy(bpmnStream,bpmnOut); IOUtils.copy(pngStream,pngOut); //關流 pngOut.close(); bpmnOut.close(); pngStream.close(); bpmnStream.close(); } }
3、效果
四、業務系統和流程系統進行關聯
通過buessinessKey字段標識業務系統的主鍵數據ID,進而表名當前業務執行到了哪一個流程
1.代碼實現
package com.zn; import org.activiti.engine.*; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.activiti.engine.task.Task; import org.apache.commons.io.IOUtils; import org.junit.Test; import java.io.*; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 啟動流程實例和業務系統關聯 * 正常應該先添加數據到業務表當中,拿到當前添加數據的主鍵ID,通過啟動流程實例,將主鍵ID交給BuessniessKkey * 代表和流程系統進行關聯 */ @Test public void startInstance() { /** * 讓張三在頁面提交,然后拿到ID */ /** * 創建張三請假的實例流程 */ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RuntimeService runtimeService = processEngine.getRuntimeService(); //生成流程 runtimeService.startProcessInstanceByKey("holiday","1"); /** * 張三提交請假審批 */ //獲取一個TaskService對象 TaskService taskService = processEngine.getTaskService(); //獲取張三的任務 Task task = taskService.createTaskQuery().taskAssignee("zhangsan").processDefinitionKey("holiday").singleResult(); //任務審批 taskService.complete(task.getId()); } }
2.數據庫
五、流程激活和掛起
1、所有流程
package com.zn; import org.activiti.engine.*; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.io.IOUtils; import org.junit.Test; import java.io.*; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 所有流程定義的掛起 */ @Test public void allSuspend(){ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取repositoryService對象 RepositoryService repositoryService = processEngine.getRepositoryService(); //獲取流程定義 ProcessDefinition holiday = repositoryService.createProcessDefinitionQuery().processDefinitionKey("holiday").singleResult(); //獲取到當前流程定義是否為暫停狀態 suspended方法為true代表為暫停 false就是運行的 boolean suspended = holiday.isSuspended(); if(suspended){ repositoryService.activateProcessDefinitionById(holiday.getId(),true,null); System.out.println("該流程定義激活"); }else{ repositoryService.suspendProcessDefinitionById(holiday.getId(),true,null); System.out.println("該流程定義暫停"); } } }
控制台效果:
再次執行效果:
2、單個流程
package com.zn; import org.activiti.engine.*; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinitionQuery; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.io.IOUtils; import org.junit.Test; import java.io.*; import java.util.List; import java.util.zip.ZipInputStream; public class ActivitiTest { /** * 單個流程實例的掛起 */ @Test public void singleSuspend(){ //獲取processEngine對象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //獲取RuntimeService對象 RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId("2501").singleResult(); //獲取到當前流程定義是否為暫停狀態 suspended方法為true代表為暫停 false就是運行的 boolean suspended = processInstance.isSuspended(); if(suspended){ runtimeService.activateProcessInstanceById("2501"); System.out.println("xx的請假流程激活"); }else{ runtimeService.suspendProcessInstanceById("2501"); System.out.println("xx的請假流程掛起"); } } }
控制台效果:
再次執行效果: