springBoot整合Activiti5.0
一、工作流簡介
1.什麼是工作流?
簡單的理解就是工作的流程,這裡的流程指的是,完成一個企業中具體業務的一系列工作步驟,所有的步驟合在一起就是業務從開始到結束的流轉過程。
從計算機系統的角度來講,工作流系統表示:業務過程的部分和整體在計算機應用環境的自動化操作。
2.工作流的三大要素
①這個過程要做什麼?
②經過多少個步驟?
③每個步驟是由誰來做,做什麼,怎麼做?
3.工作流系統的組成
流程定義工具:定義流程(畫流程圖)
表單定製工具:要提交的資料的表單的定製(可以用建立一個(html form)表單的表單形式替代)
工作流引擎: 工作流框架的核心,驅動著流程的流程,流程的資料共享,資料儲存,流程的版本迭代....
管理監控工具:監控每一個流程的運轉,管理每一個流程;
開發API:暴露給開發人員的api;
4.工作流需要解決的問題
1)、流程的自動化流程控制
2)、流程資料的儲存(歷史記錄,歷史資料的儲存);
3)、流程版本的更替;(維護流程的版本更替);
4)、流程執行期間資料的共享等;
流程都具有一定的通用性;流程框架抽取流程的通用性,來統一管理和維護流程;
5.工作流的相關概念
①流程定義:(ProcessDefinition):
流程的定義:流程圖。表示一個流程的資訊;一個流程定義(如:請假流程圖)
②流程例項:(ProcessInstance):
啟動一個流程:稱為建立一個流程的例項;無數個流程例項(如員工提交的請假單審批流程)
③流程變數:(ProcessVariable):
流程執行提交的資料,共享的資料,等;
④任務:(Task)
每一步需要完成的工作算是一個任務;(每一個流程執行都需要完成自己的流程規定的任務)
⑤開始、結束(Start 、End)
每一個流程只有一個入口,無數的出口;(正常結束的出口,異常結束的出口等)
⑥閘道器(Gateway):
流程的分支節點(判斷節點);決定下一步走哪兒;
6.工作流產品
①JBPM
②OSWorkFlow
③Shark
④信雅達
⑤普元工作流
⑥Activiti5
7.ProcessEngine
ProcessEngine這個類是Activiti5的核心,所有的服務都需要通過ProcessEngine來建立,該類是執行緒安全的
Activiti5的持久化層採用的是Mybatis,這樣移植性好,底層Spring+MyBatis;
Activiti5主要包括7個Service,這些Service都是通過ProcessEngine建立
repositoryService(持久化服務)
runtimeService(執行時服務)
formService(表單服務)
identityService(身份資訊)
taskService(任務服務)
historyService(歷史資訊)
managementService(管理定時任務)
8.Activiti5框架表結構
Activiti使用到的表都是ACT_開頭的。
ACT_RE_*: ‘RE’表示repository(儲存),RepositoryService介面所操作的表。帶此字首的表包含的是靜態資訊,如,流程定義,流程的資源(圖片,規則等)。
ACT_RU_*: ‘RU’表示runtime,執行時表-RuntimeService。這是執行時的表儲存著流程變數,使用者任務,變數,職責(job)等執行時的資料。Activiti只儲存例項執行期間的執行時資料,當流程例項結束時,將刪除這些記錄。這就保證了這些執行時的表小且快。
ACT_ID_*: ’ID’表示identity (組織機構),IdentityService介面所操作的表。使用者記錄,流程中使用到的使用者和組。這些表包含標識的資訊,如使用者,使用者組,等等。
ACT_HI_*: ’HI’表示history,歷史資料表,HistoryService。就是這些表包含著流程執行的歷史相關資料,如結束的流程例項,變數,任務,等等
ACT_GE_*: 全域性通用資料及設定(general),各種情況都使用的資料。
act_ge_bytearray二進位制資料表
act_ge_property屬性資料表儲存整個流程引擎級別的資料,初始化表結構時,會預設插入三條記錄,
act_hi_actinst歷史節點表
act_hi_attachment歷史附件表
act_hi_comment歷史意見表
act_hi_identitylink歷史流程人員表
act_hi_detail歷史詳情表,提供歷史變數的查詢
act_hi_procinst歷史流程例項表
act_hi_taskinst歷史任務例項表
act_hi_varinst歷史變量表
act_id_group使用者組資訊表
act_id_info使用者擴充套件資訊表
act_id_membership使用者與使用者組對應資訊表
act_id_user使用者資訊表
act_re_deployment部署資訊表
act_re_model流程設計模型部署表
act_re_procdef流程定義資料表
act_ru_event_subscr throwEvent、catchEvent時間監聽資訊表
act_ru_execution執行時流程執行例項表
act_ru_identitylink執行時流程人員表,主要儲存任務節點與參與者的相關資訊
act_ru_job執行時定時任務資料表
act_ru_task執行時任務節點表
act_ru_variable執行時流程變數資料表
9.流程框架的標準
Business Process Management (BPM). 工作流管理系統
BPMN 2.0:Business Process Modeling Notation(中文:業務流程建模與標註)
OMG組織維護業務流程建模規範,以後所有流程框架繪製流程圖都遵循這個規範;
二、流程框架的操作
1)、設計流程:畫流程圖;
2)、儲存流程:給資料庫中儲存繪製的流程圖(流程定義)
3)、匯出流程:實際上繪製的流程是一個xml檔案;bmpn規範;
<?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: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="電話費報銷" name="話費報銷" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="usertask1" name="部門經理審批"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<userTask id="usertask2" name="財務審批"></userTask>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<userTask id="usertask3" name="總經理審批"></userTask>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_電話費報銷">
<bpmndi:BPMNPlane bpmnElement="電話費報銷" id="BPMNPlane_電話費報銷">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="90.0" y="190.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="170.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="320.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="470.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="640.0" y="190.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="125.0" y="207.0"></omgdi:waypoint>
<omgdi:waypoint x="170.0" y="207.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="275.0" y="207.0"></omgdi:waypoint>
<omgdi:waypoint x="320.0" y="207.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="425.0" y="207.0"></omgdi:waypoint>
<omgdi:waypoint x="470.0" y="207.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="575.0" y="207.0"></omgdi:waypoint>
<omgdi:waypoint x="640.0" y="207.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
<process></process>規定整個流程的流轉;
<userTask ></userTask>規定使用者任務;
<sequenceFlow></sequenceFlow>指定流轉方向等...
4)、流程部署:實際就是把流程的定義資訊(詳情)儲存到資料庫; 給資料儲存了流程定義
5)、啟動流程:按照流程定義啟動一次流程(流程例項)
6)、流程例項:流程框架控制自動流轉到下一步;
7)、簽收任務完成任務;完成以後,流程框架自動判斷來到下一步
8)、檢視歷史流程
三、Activiti5框架的幾大元件
ProcessEngine :流程框架的核心 ;獲取各大元件
activiti的七大元件:都是由流程引擎得到的;
以下為元件的獲取方式:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
四、Activiti5的使用
1.導包(Activiti5預設使用的是h2的記憶體資料庫,如果要使用mysql需要匯入響應的驅動包)
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>5.22.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
2.編寫流程框架配置檔案(檔名:activiti.cfg.xml)
<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">
<!-- id必須是這個名稱 -->
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--資料庫的連線相關資訊 -->
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="123456" />
<!-- 第一次啟動創鍵資料庫;以後升級資料庫表結構 -->
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="false" />
<!--設定解決亂碼問題 -->
<property name="activityFontName" value="微軟雅黑"></property>
<property name="annotationFontName" value="微軟雅黑"></property>
<property name="labelFontName" value="微軟雅黑"></property>
</bean>
</beans>
3.獲取流程引擎
public static void main(String[] args) {
//第一次獲取流程引擎會建立很多表
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
System.out.println(engine.toString());
}
第一次建立資料表時,此表中會有三條記錄:
五、在eclipse中使用activiti5繪製流程圖
1.安裝繪製流程圖的外掛
2.部署流程(把流程定義(流程圖)儲存到資料庫中);每次部署產生一個【流程定義】
/**
* 部署專案
*/
@Test
public void testDeployement() {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("話費報銷流程.bpmn").deploy();
System.out.println(deployment.getName());
System.out.println(deployment.getId());
System.out.println(deployment.getDeploymentTime());
}
資料庫效果:
act_ge_bytearray
act_re_deployment
act_re_procdef
id_:流程定義的唯一id;流程引擎自動生成的;
rev_:資料庫樂觀鎖機制
category_:分類
name_:流程定義的名字
key_:流程定義的key
version_:流程的版本號
deployment_id:那次部署產生的這個流程定義
resource_name_:流程定義的xml檔案的名字;
dgrm_resource_name_:流程圖的檔案的名字;
其他等等的資訊...
每一個流程圖都有三個資料;
同一個流程部署多次會產生多個版本;根據每一個流程圖的id來區分;
3.查詢流程部署資訊
/**
* 檢視資料庫的流程部署資訊
*/
@Test
public void testQueryPdeployment() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
List<Deployment> list = deploymentQuery.list();
for (Deployment deployment : list) {
System.out.println("部署流程id"+deployment.getId());
System.out.println("部署流程名字"+deployment.getName());
System.out.println("部署流程時間"+deployment.getDeploymentTime());
}
}
4.查詢流程定義資訊
/**
* 檢視資料庫的流程定義資訊
*/
@Test
public void testQueryPdefintion(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//獲取資料庫中所有的流程定義資訊
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition processDefinition : list) {
System.out.println("部署的定義目錄"+processDefinition.getCategory());
System.out.println("部署的定義id"+processDefinition.getDeploymentId());
System.out.println("部署的定義key"+processDefinition.getKey());
System.out.println("部署的定義name"+processDefinition.getName());
System.out.println("部署的定義版本"+processDefinition.getVersion());
System.out.println("部署的定義流程圖資源名"+processDefinition.getDiagramResourceName());
}
}
3.啟動流程
/**
* 啟動一個流程
*/
@Test
public void testStart() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionVersion(2).singleResult();
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
System.out.println("流程啟動完成"+processInstance);
}
4.查詢任務,簽收任務
如果某個任務已經固定分配給某個人了,就不能再簽了;如果要籤,先要撤銷簽收unclaim;
/**
* 查詢當前流程執行的任務;
*/
@Test
public void testQueryTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
//查詢當前任務
Task task = taskService.createTaskQuery().singleResult();
System.out.println(task);
//簽收任務
taskService.claim(task.getId(), "admin");
System.out.println("admin簽收了"+task);
}
5.執行任務,並自動流轉到下一個流程
/**
* 執行任務
*/
@Test
public void testQueryTaskByUser() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
//獲取admin要執行的任務
Task task = taskService.createTaskQuery().taskAssignee("admin").singleResult();
//執行任務
taskService.complete(task.getId());
System.out.println("admin完成任務"+task);
}
6.查詢任務的執行歷史
/**
* 查詢任務的執行歷史
*/
@Test
public void testHistory() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//獲取HistoryService進行歷史任務的檢索等操作
HistoryService historyService = processEngine.getHistoryService();
//查詢所有已經完成的流程例項
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processFinished().list();
for (HistoricTaskInstance historicTaskInstance : list) {
//查詢那個歷史任務是由誰在什麼時間開始,在什麼時間結束
System.out.println(historicTaskInstance);
System.out.println(historicTaskInstance.getName()+"===>"+historicTaskInstance.getAssignee()+"===>"+historicTaskInstance.getStartTime()+"===>"+historicTaskInstance.getEndTime());
}
}