在工作流中,我們一切工作流的基本就是工作引擎(ProcessEngine),繼承於EngineService接口,包括流程部署,數據庫連接都是靠着ProcessEngine來實現的。而ProcessEngineConfiguration:流程引擎配置,可以設置數據庫等,默認的數據庫是h2,持久化實現使用的Mybatis,這裏我們用的是mysql。
那麼既然無論是jbpm或者是activiti都需要ProcessEngine來驅動,那麼我們就說一下工作流引擎的使用吧。
流程部署
當我們將我們的業務畫成圖的時候,然後利用工作流引擎部署,也就是將我們的流程圖信息放到數據庫,圖和代碼如下:
[java] view plain copy
/**部署流程定義*/
@Test
public void deploymentProcessDefinition(){
Deployment deployment = processEngine.getRepositoryService() //用於流程定義和部署相關對象的Service
.createDeployment() //創建一個部署對象
.name("leaveBill部門程序")
.addClasspathResource("diagrams/LeaveBill.bpmn") //從ClassPath資源中加載,一次只能加載一個文件
.addClasspathResource("diagrams/LeaveBill.png") //從ClassPath資源中加載,一次只能加載一個文件
.deploy();
System.out.println("deployment" + deployment.getId()); //1
System.out.println("deployment" + deployment.getName());//部門程序
}
打印結果如下:
deployment1
deploymenthellworld部門程序
數據庫(部署相關表)解析
我們看一下數據庫的表會發現,每次部署都是涉及的那三張表,act_re_deployment(流程部署表)
該表包含了流程部署的名稱,ID,和部署時間
act_re_procdef(流程定義表)
該表有流程定義的主鍵key,版本(version)源文件名和圖示,還有流程定義ID(key + 版本號+隨機生成的數字)
act_ge_bytearray(資源文件表)
保存了資源的位置和存儲方式和部署ID,版本號ID等信息
act_ge_property:主鍵生成策略表
定義了主鍵生成的策略信息
執行流程
顧名思義,就是當我們有一個人開始申請請假的時候我們就要執行該請假的流程實例了
[java] view plain copy
/**
* 執行流程實例
*/
@Test
public void startProcessInstance(){
String processInstanceKey = "LeaveBill";
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey(processInstanceKey);
System.out.println("流程實例id:" + pi.getId()); //流程實例id 101
System.out.println("流程定義id:" + pi.getProcessDefinitionId()); //流程定義ID helloworld:1:4
}
這樣我們的流程實例就啓動起來了,那麼接下來我們看一下在啓動流程實例的時候我們涉及到的表信息
數據庫分析(實例表)分析
act_ru_execution: 正在執行的執行對象表,側重流程實例,對象,任務
包含了實例ID,流程定義ID,要執行的任務名稱(usertask1)等信息
act_ru_task:正在執行的任務表,對具體的任務而言,任務執行到哪裏了
act_ru_identitylink流程信息變量act_hi_taskinst:已經執行完的歷史任務信息
act_hi_taskinst:已經執行完的歷史任務信息
act_hi_procinst:流程實例的歷史表,存放執行完畢的流程實例信息
act_hi_actinst:存放歷史所有完成的活動
現在我們對錶有一個大致的瞭解,那麼接下來我們就按照我們既定的流程去執行我們的請假,例如第一個項目經理叫張三,那麼這個流程實例已啓動,首先需要張三去執行操作,那麼我們我們看一下張三的執行任務的詳情,代碼如下:
[java] view plain copy
/**
* 查找個人當前的要執行的任務
*/
@Test
public void findMyTaskInfo(){
String assignee = "張三";
List<Task> listTask = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee(assignee)
.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("執行對象的ID:" + task.getExecutionId());
System.out.println("任務的班裏人:" + task.getAssignee());
System.out.println("流程定義ID:" + task.getProcessInstanceId());
}
}
}
打印信息如下:任務ID:304,任務名稱:【項目經理】審批,任務時間:Sat Jan 23 14:54:35 CST 2016,任務的班裏人:張三 任務的實例ID:LeaveBill:2:204 執行對象的ID:301 任務的班裏人:張三 流程定義ID:301
任務完成
那麼接下來我就把任務ID爲304的一個流程結束,也就是項目經理同意請假,代碼如下:
[java] view plain copy
/**完成任務*/
@Test
public void completeMyPersoinTask() {
String taskId = "304";
processEngine.getTaskService()
.complete(taskId);
System.out.println("完成任務,任務ID:" + taskId);
}
然後我繼續執行查詢個人任務的時候,我們只能查到主任的任務了,因爲項目經理已經執行完畢,所以當前執行的任務是看不到的,但是在歷史信息中是存在的。
如果我們啓動了實例的話,查詢當前信息的話,實在act_ru_*的表中查詢,根據任務有關的服務,都是taskService,當然Activiti還有很多的服務,例如RepositoryService,RuntimeService, HistoryService等服務。
大致總結一下,就是先部署,再啓動,個人登陸系統後,根據個人姓名,查到任務ID,完成個人任務,直到全部完成