一、什么是流程定義
流程定義是線下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());
}
}
將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());
}
}
五、流程激活和掛起
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的請假流程掛起");
}
}
}