Activiti7入門學習

什麼是工做流

工做流(Workflow),就是經過計算機對業務流程自動化執行管理。它主要解決的是「使在多個參與者之間按照某種預約義的規則自動進行傳遞文檔、信息或任務的過程,從而實現某個預期的業務目標,或者促使此目標的實現」。java

什麼是Activiti7

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.jpg

Activit如何使用

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)流程結束
當任務辦理完成沒有下一個任務/結點了,這個流程實例就完成了。

Activiti入門體驗

1.安裝Activiti Designer插件
在IDEA的File菜單中找到子菜單」Settings」,後面咱們再選擇左側的「plugins」菜單,搜索actiBPM插件,安裝成功後以下圖所示:
1.jpg
重啓IDEA就可使用了

2.數據庫表的命名規則
Activiti的表都以ACT_開頭。第二部分是表示表的用途的兩個字母標識。用途也和服務的API對應。

  • ACT_RE_*: 'RE'表示repository。這個前綴的表包含了流程定義和流程靜態資源(圖片,規則,等等)。
  • ACT_RU_*: 'RU'表示runtime。這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。Activiti只在流程實例執行過程當中保存這些數據,在流程結束時就會刪除這些記錄。這樣運行時表能夠一直很小速度很快。
  • ACT_HI_*: 'HI'表示history。這些表包含歷史數據,好比歷史流程實例,變量,任務等等。
  • ACT_GE_*:GE表示general。通用數據,用於不一樣場景下。

3.ProcessEngine
工做流引擎,至關於一個門面接口,經過ProcessEngineConfiguration建立processEngine,經過ProcessEngine建立各個service接口。

  • RepositoryService
    是activiti的資源管理類,提供了管理和控制流程發佈包和流程定義的操做。使用工做流建模工具設計的業務流程圖須要使用此service將流程定義文件的內容部署到計算機
  • RuntimeService
    它是activiti的流程運行管理類。能夠從這個服務類中獲取不少關於流程執行相關的信息
  • TaskService
    是activiti的任務管理類。能夠從這個類中獲取任務的信息
  • HistoryService
    是activiti的歷史管理類,能夠查詢歷史信息,執行流程時,引擎會保存不少數據(根據配置),好比流程實例啓動時間,任務的參與者,完成任務的時間,每一個流程實例的執行路徑,等等。這個服務主要經過查詢功能來得到這些數據。
  • ManagementService
    是activiti的引擎管理類,提供了對Activiti 流程引擎的管理和維護功能,這些功能不在工做流驅動的應用程序中使用,主要用於Activiti 系統的平常維護

4.新建流程
1)首先選中存放圖形的目錄(選擇resources下的bpmn目錄),點擊菜單:New-BpmnFile
1574327400(1).jpg

2)繪製流程
1.jpg

3)指定任務負責人
1.jpg

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數據庫。
1.jpg

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());
    }
}

1.jpg

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("==============================");
        }
    }
}

1.jpg

相關文章
相關標籤/搜索