工做流(Workflow),就是經過計算機對業務流程自動化執行管理。它主要解決的是「使在多個參與者之間按照某種預約義的規則自動進行傳遞文檔、信息或任務的過程,從而實現某個預期的業務目標,或者促使此目標的實現」。java
1)Activiti介紹
Activiti是一個工做流引擎,activiti能夠將業務系統中複雜的業務流程抽取出來,使用專門的建模語言(BPMN2.0)進行定義,業務系統按照預先定義的流程進行執行,實現了業務系統的業務流程由activiti進行管理,減小業務系統因爲流程變動進行系統升級改造的工做量,從而提升系統的健壯性,同時也減小了系統開發維護成本。官方網站:https://www.activiti.org/數據庫
2)BPMN
BPMN(Business Process Model And Notation)-業務流程模型和符號是由BPMI(Business Process Management Initiative)開發的一套標準的業務流程建模符號,使用BPMN提供的符號能夠建立業務流程。segmentfault
Activiti 就是使用BPMN 2.0 進行流程建模、流程執行管理,它包括不少的建模符號,好比:Event 用一個圓圈表示,它是流程中運行過程當中發生的事情。api
一個bpmn圖形的例子:異步
1)部署activiti
Activiti是一個工做流引擎(其實就是一堆jar包API),業務系統使用activiti來對系統的業務流程進行自動化管理,爲了方便業務系統訪問(操做)activiti的接口或功能,一般將activiti環境與業務系統的環境集成在一塊兒。ide
2)流程定義
使用activiti流程建模工具(activity-designer)定義業務流程(.bpmn文件)。.bpmn文件就是業務流程定義文件,經過xml定義業務流程。工具
3)流程定義部署
向activiti部署業務流程定義(.bpmn文件)。使用activiti提供的api向activiti中部署.bpmn文件(通常狀況還須要一起部署業務流程的圖片.png)網站
4)啓動一個流程實例(ProcessInstance)
啓動一個流程實例表示開始一次業務流程的運行,好比員工請假流程部署完成,若是張三要請假就能夠啓動一個流程實例,若是李四要請假也啓動一個流程實例,兩個流程的執行互相不影響,就比如定義一個java類,實例化兩個對象同樣,部署的流程就比如java類,啓動一個流程實例就比如new一個java對象。編碼
5)用戶查詢待辦任務(Task)
由於如今系統的業務流程已經交給activiti管理,經過activiti就能夠查詢當前流程執行到哪了,當前用戶須要辦理什麼任務了,這些activiti幫咱們管理了spa
6)用戶辦理任務
用戶查詢待辦任務後,就能夠辦理某個任務,若是這個任務辦理完成還須要其它用戶辦理,好比採購單建立後由部門經理審覈,這個過程也是由activiti幫咱們完成了,不須要咱們在代碼中硬編碼指定下一個任務辦理人了。
7)流程結束
當任務辦理完成沒有下一個任務/結點了,這個流程實例就完成了。
1.安裝Activiti Designer插件
在IDEA的File菜單中找到子菜單」Settings」,後面咱們再選擇左側的「plugins」菜單,搜索actiBPM插件,安裝成功後以下圖所示:
重啓IDEA就可使用了
2.數據庫表的命名規則
Activiti的表都以ACT_開頭。第二部分是表示表的用途的兩個字母標識。用途也和服務的API對應。
3.ProcessEngine
工做流引擎,至關於一個門面接口,經過ProcessEngineConfiguration建立processEngine,經過ProcessEngine建立各個service接口。
4.新建流程
1)首先選中存放圖形的目錄(選擇resources下的bpmn目錄),點擊菜單:New-BpmnFile
2)繪製流程
3)指定任務負責人
4)搭建工做流項目,部署流程定義,參考https://segmentfault.com/a/11...,要將上邊繪製的圖形即流程定義(.bpmn)部署在工做流程引擎activiti中
/** * 流程定義的部署 * activiti表有哪些? * act_re_deployment 部署信息 * act_re_procdef 流程定義的一些信息 * act_ge_bytearray 流程定義的bpmn文件及png文件 */ @Test public void createDeploy() { RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("diagram/holiday.bpmn")//添加bpmn資源 .addClasspathResource("diagram/holiday.png") .name("請假申請單流程") .deploy(); log.info("流程部署id:" + deployment.getName()); log.info("流程部署名稱:" + deployment.getId()); }
執行此操做後activiti會將上邊代碼中指定的bpm文件和圖片文件保存在activiti數據庫。
5)啓動一個流程實例
流程定義部署在activiti後就能夠經過工做流管理業務流程了,也就是說上邊部署的請假申請流程可使用了。
針對該流程,啓動一個流程表示發起一個新的請假申請單,這就至關於java類與java對象的關係,類定義好後須要new建立一個對象使用,固然能夠new多個對象。
對於請假申請流程,張三發起一個請假申請單須要啓動一個流程實例,李四發起一個請假單也須要啓動一個流程實例。
/** * 啓動流程實例: * 前提是先已經完成流程定義的部署工做 * <p> * 背後影響的表: * act_hi_actinst 已完成的活動信息 * act_hi_identitylink 參與者信息 * act_hi_procinst 流程實例 * act_hi_taskinst 任務實例 * act_ru_execution 執行表 * act_ru_identitylink 參與者信息 * act_ru_task 任務 */ @Test public void startProcessInstance() { RuntimeService runtimeService = processEngine.getRuntimeService(); //啓動流程實例 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday"); log.info("流程定義ID:" + processInstance.getProcessDefinitionId()); log.info("流程實例ID:" + processInstance.getId()); }
6)任務查詢
流程啓動後,各各任務的負責人就能夠查詢本身當前須要處理的任務,查詢出來的任務都是該用戶的待辦任務。
/** * 查詢當前用戶的任務列表 */ @Test public void findPersonalTaskList() { TaskService taskService = processEngine.getTaskService(); //根據流程定義的key,負責人assignee來實現當前用戶的任務列表查詢 List<Task> taskList = taskService.createTaskQuery() .processDefinitionKey("holiday") .taskAssignee("張三") .list(); for (Task task : taskList) { System.out.println("-----------------------"); System.out.println("流程實例ID:" + task.getProcessInstanceId()); System.out.println("任務ID:" + task.getId()); System.out.println("任務負責人:" + task.getAssignee()); System.out.println("任務名稱:" + task.getName()); } }
7)任務處理
任務負責人查詢待辦任務,選擇任務進行處理,完成任務。
/** * 處理當前用戶的任務 * 背後操做的表: * act_hi_actinst * act_hi_identitylink * act_hi_taskinst * act_ru_identitylink * act_ru_task */ @Test public void completeTask() { String processDefinitionKey = "holiday"; TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey) .taskAssignee("張三").singleResult(); if(task != null){ //處理任務,結合當前用戶任務列表的查詢操做的話 taskService.complete(task.getId()); log.info("處理完成當前用戶的任務"); }else{ log.info("當前用戶暫無任務"); } }
8)查詢歷史
@Test public void queryHistory() { HistoryService historyService = processEngine.getHistoryService(); RepositoryService repositoryService = processEngine.getRepositoryService(); //查詢流程定義 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); String processDefinitionKey = "holiday"; //遍歷查詢結果 ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey(processDefinitionKey) .orderByProcessDefinitionVersion().desc().singleResult(); if (processDefinition != null) { HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery(); List<HistoricActivityInstance> list = query.processDefinitionId(processDefinition.getId()) .orderByHistoricActivityInstanceStartTime().asc().list();//排序StartTime for (HistoricActivityInstance ai : list) { System.out.println(ai.getActivityId()); System.out.println(ai.getActivityName()); System.out.println(ai.getProcessDefinitionId()); System.out.println(ai.getProcessInstanceId()); System.out.println("=============================="); } } }