1. 程式人生 > >Activiti工作流入門(上)

Activiti工作流入門(上)

工作流 1)概念:多個人一起完成某件事情的過程,把這個過程變成計算機識別的形式就是工作流; 2)常見的工作流框架:Activiti、JBPM 3)Activiti的優點: 提高系統柔性,適應業務流程的變化; 實現更好的業務控制過程、提高服務質量 降低維護成本和系統開發人力 4)Activiti核心物件介紹

  1. 1)工作流引擎ProcessEngine Activiti的核心物件,它負責生成流程時需要的各種例項的資料、監控時維護;
  2.  2)Activiti流程定義語言BPMN(XML)
  3. 3)Activiti資料庫持久化

     -  ACT_RE_*: 'RE'表示repository,這個表開頭的是包含了定義流程和靜態資源(圖片、規則) ACT_RU_*:   

    -   'RU'表示runtime,執行時的流程例項相關的資訊,開啟流程後到結束所有的例項資料都儲存在這裡; ACT_ID_*:   

    -   'ID'表示identity,身份相關資訊 ACT_HI_*:   

    -   'HI'表示history,這些表包含歷史資料,比如歷史流程例項、具體的活動歷史流程例項; ACT_GE_*: 通用資料,   

       用於不同場景下。(上傳的流程圖儲存在裡面)

5)使用Activiti

        a、準備eclipse的Activiti外掛壓縮包         百度雲資源:https://pan.baidu.com/s/1oZX8_rZZmXGAbWqn_amRog

        b、把壓縮包中的內容(Activiti)放入eclipse根目錄的dropins資料夾下         c、建立web專案,並匯入包(全部)         百度雲資源全部jar: https://pan.baidu.com/s/1xxGn9K1PIVs_gbLibwHqzw         選擇下面的就可以了,差啥導啥                 d、得到工作流的核心物件ProcessEngine(三種方式)         編碼方式

           // 建立ProcessEngine引擎物件:就會自動建立資料和25張表
            @Test
            public void createProcessEngine1() {
            //是一個介面:我們需要去連線資料庫,肯定需要很多連線資訊,就是配置資訊
            //所以先做配置物件,再通過配置物件構建引擎
            // ProcessEngine  建立引擎的配置物件
            ProcessEngineConfiguration configuration=
            ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
            //做引擎配置物件的配置
            configuration.setJdbcUrl("jdbc:mysql:///activiti? 
                                            createDatabaseIfNotExist=true");
            configuration.setJdbcDriver("com.mysql.jdbc.Driver");
            configuration.setJdbcUsername("root");
            configuration.setJdbcPassword("000000");
            //設定建立資料庫表的策略:true:建立
           configuration.setDatabaseSchemaUpdate
                              (ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
            //通過引擎配置物件構建引擎
            ProcessEngine pe = configuration.buildProcessEngine();
            // 
[email protected]
            System.out.println(pe);         }

 配置方式(resource下的activiti.cfg.xml)

  @Test
        public void createProcessEngine2() throws Exception {
            /**
             * 讓建立的配置物件 載入配置檔案建立引擎物件
             */
            try {
                ProcessEngineConfiguration configuration = 
                        ProcessEngineConfiguration.
                        createProcessEngineConfigurationFromResource("activiti.cfg.xml");
                ProcessEngine processEngine = configuration.buildProcessEngine();
                //[email protected]
                System.out.println(processEngine);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

最佳實踐方式(推薦)

    /**
         * 配置檔案都是按照一定規則來的:activiti.cfg.xml有統一的命名規範,,放在resource下
         * 使用框架提供的預設方法建立
         * @throws Exception
         */
        @Test
        public void creatProcessEngine3() throws Exception {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            //[email protected]
            System.out.println(processEngine);
        }

6)學習導讀 6.1)使用Activiti繪圖,會產生兩個檔案:bpmn(流程定義檔案),png(流程圖) 右鍵建立資原始檔

6.2)部署流程的核心物件ProcessDefinition 6.2.1)部署流程

    /**
         * @throws Exception
         *流程定義(規則)管理--核心(ProcessDefinition)
         * 1、部署流程 
         * 2、流程定義列表查詢
         * 3、刪除流程(刪除部署,流程的掛起和啟用)
         * 4、檢視規則流程圖 (沒有修改,刪除了重新部署!!)
         *  涉及的資料庫三張表:
         * 1)act_re_deployment 部署資訊表:部署一次就有一條記錄
         * 2)act_re_procdef 流程定義資料表:部署一次,就產生一個流程,有一個流程定義資料
         * 3)act_ge_bytearray二進位制資料表:一個流程定義會有有兩個2機制資料:.bpmn和png的資料
         */
        @Test
        public void processDefinitionTest() throws Exception {
            // 1 拿到核心物件 首先獲得預設的流程引擎,在建立時會自動載入classpath下得activiti.cfg.xml
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            // 2 通過核心物件拿到服務例項 倉庫服務類:bpmn檔案和流程圖片
            RepositoryService repositoryService = processEngine.getRepositoryService();
            // 3 通過倉庫服務物件部署一個builder 用來封裝部署環境的相關配置
            DeploymentBuilder builder = repositoryService.createDeployment();
            // 部署兩個資原始檔bpmn和png圖片
            builder.addClasspathResource("LeaveProcess.bpmn")
            .addClasspathResource("LeaveProcess.png").name("員工離職_verson1");
            // 4 使用服務的方法做事情
            Deployment deployment = builder.deploy();
            System.out.println(deployment);
        }

啟動部署後建立的資料表 6.2.2)流程定義列表查詢

// 檢視定義的流程列表資訊
        @Test
        public void processDefinitedList() throws Exception {
            // 1 獲取核心物件
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            // 2 通過核心物件,獲取服務物件 流程定義的資訊存放在倉庫中,所以應該獲取RepositoryService
            RepositoryService repositoryService = processEngine.getRepositoryService();
            // 3 使用服務做事情 查詢
            // 建立查詢物件
            ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
            // 設定查詢條件
            // deploymentQuery.processDefinitionKey("myProcess");
            // definitionQuery.processDefinitionKey(processDefinitionKey)
            // definitionQuery.processDefinitionKeyLike(processDefinitionKeyLike)
            // definitionQuery.processDefinitionName(processDefinitionName)
            // definitionQuery.processDefinitionNameLike(processDefinitionNameLike)
            // 執行查詢
            // System.out.println(definitionQuery.count());
            // definitionQuery.count();//查詢總的條數
            // definitionQuery.list();//查詢所有的流程定義
            // definitionQuery.singleResult();//查詢唯一記錄
            // definitionQuery.listPage(firstResult, maxResults);//分頁查詢
            // 查詢全部
            List<ProcessDefinition> list = definitionQuery.list();
            // 迴圈查詢結果
            for (ProcessDefinition pD : list) {
                System.out.println("id=" + pD.getId());
                System.out.println("name=" + pD.getName());
                System.out.println("category=" + pD.getCategory());
                System.out.println("resourceName=" + pD.getResourceName());
                System.out.println("DeployementId=" + pD.getDeploymentId());
                System.out.println("key使用者定義不同的流程" + pD.getKey());
            }
        }

6.2.3)刪除流程(刪除部署,流程的掛起和啟用)

/**
         * 刪除流程定義(刪除部署,就刪除了流程定義) --> 使用流程掛起和啟用來實現流程的刪除.物理刪除也許失敗 因為有外來鍵
         */
        @Test
        public void delProcess() throws Exception {
            try {
                // 1 獲取核心引擎物件
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                // 2 拿到服務物件例項
            RepositoryService repositoryService = processEngine.getRepositoryService();
            String deploymentId = "5001";
                // 3 呼叫服務物件的方法
                // 使用服務的方法做事情:刪除一個部署,就刪除一個流程定義
                repositoryService.deleteDeployment(deploymentId);//物理刪除
                //String processDefinitionKey="myProcess";//定義流程的key值
                //邏輯刪除:掛起 suspend,其實是修改某個欄位的狀態suspension_state 1啟用 2掛起
                //repositoryService.suspendProcessDefinitionByKey(processDefinitionKey);
                //啟用 
                //String processDefinitionKey="myProcess";
                //repositoryService.activateProcessDefinitionByKey(processDefinitionKey);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }}

6.2.4)檢視規則流程圖(沒有修改,刪除了重新部署!!)    

        // 檢視規則流程圖 查詢出流程定義文件。主要查的是圖片,用於顯示流程用
        @Test
        public void viewProcessDiagram() throws Exception {
            try {
                // 獲取核心物件
                ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
                // 分析需求,通過核心物件獲取對應的"服務例項"
                RepositoryService repositoryService = engine.getRepositoryService();
                // 使用服務方法做事情
                String deploymentId = "5001";//deploymentId為流程部署ID
                String resourceName = "Myprocess.png";//act_ge_bytearray表中NAME_列的值
                // 通過流的方式獲取,以後在做專案的時候直接複製到response中就可以輸出了
                InputStream resourceAsStream = 
                    repositoryService.getResourceAsStream(deploymentId, resourceName);
                // 輸出到本地
                IOUtils.copy(resourceAsStream, new FileOutputStream(new 
                                                                 File("d://9.png")));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }    

7)流程執行時管理核心物件ProcessInstance 7.1)啟動流程

            // act_ru_execution:儲存流程的相關資訊
            // act_ru_identifylink 執行介紹 該表資料消失
            // act_ru_task 如果該表是有人蔘與的流程節點 那麼是對execution的補充
            @Test
            public void startProcessInstance() throws Exception {
                // 拿到大管家
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                // 拿到相應的服務物件 啟動例項,啟動後就運行了,使用執行服務
                RuntimeService runtimeService = processEngine.getRuntimeService();
                // 呼叫服務物件的方法做事情
                String processDefinitionKey = "leaveProcess";// 定義流程的key
                // 啟動流程例項
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
                System.out.println("instanceId:" + processInstance.getId());
                System.out.println("instanceIName:" + processInstance.getName());
                // 操作資料庫的act_ru_execution表,如果是使用者任務節點,同時也會在act_ru_task新增一條記錄
            }

7.2)檢視任務         私有任務

            // 檢視有人蔘與的節點 的//私有任務
            @Test
            public void viewPersonTask() throws Exception {
                // 拿到核心物件
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                // 拿到服務物件例項 啟動例項
                TaskService taskService = processEngine.getTaskService();
                // 呼叫服務物件的方法做事情
                // 查詢得先建立一個查詢物件
                TaskQuery taskQuery = taskService.createTaskQuery();
                String assignee = "yang";
                // 設定yang的任務 查詢條件
                taskQuery.taskAssignee(assignee); // taskAssignee指定任務的候選者
                // 執行查詢操作
                List<Task> list = taskQuery.list();
                for (Task task : list) {
                    // Task[id=2504, name=????]
                    System.out.println(task);
                }
            }

    ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20181111180303562.png)    公共任務

         // 檢視任務:公共任務
            @Test
            public void commandTask() throws Exception {
                try {
                    // 1 拿到核心物件
                    ProcessEngine processEngine =     
                                             ProcessEngines.getDefaultProcessEngine();
                    // 2 拿到服務物件
                    TaskService taskService = processEngine.getTaskService();
                    // 3 呼叫服務物件的方法
                    // 拿到查詢物件
                    TaskQuery taskQuery = taskService.createTaskQuery();
                    // 4 執行查詢
                    taskQuery.taskCandidateUser("tang");
                    List<Task> list = taskQuery.list();
                    for (Task task : list) {
                        System.out.println(task);
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

7.3)認領任務

/**
         * 任務認領:對於公有任務,可以認領。一旦認領後,自己就不再有這個任務
         */
        @Test
        public void claimTask() throws Exception {
            ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
            TaskService taskService = processEngine.getTaskService();
            String taskId="2505";
            String userId="liu";
            //確定被認領的任務ID和認領人ID
            taskService.claim(taskId, userId);
        }

7.4)完成任務

 // 指定任務ID,完成該任務。
        // 辦理任務
        @Test
        public void completeProcess() {
            try {
                // 流程執行
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                // 流程啟動後,辦理是人在辦理,使用taskService
                TaskService taskService = processEngine.getTaskService();
                // 表:act_ru_task
                taskService.complete("2504");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

7.5)檢視流程例項歷史狀態

 // 檢視使用者按照某個流程規則執行了多少次流程
        @Test
        public void processDefinitionHistoryTest() throws Exception {
            // 1 獲取核心鍍錫
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            // 2 拿到歷史服務物件例項
            HistoryService historyService = processEngine.getHistoryService();
            // 3 通過服務物件方法做事情
            // 建立歷史例項查詢物件
            HistoricProcessInstanceQuery historicProcessInstanceQuery = 
                                    historyService.createHistoricProcessInstanceQuery();
            historicProcessInstanceQuery.processInstanceBusinessKey("leaveProcess");
            // 執行查詢
            List<HistoricProcessInstance> list = historicProcessInstanceQuery.list();
            for (HistoricProcessInstance historicProcessInstance : list) {
                System.out.println(historicProcessInstance);
            }
        }

7.6)檢視活動流程例項歷史狀態

  // 檢視某次流程的執行執行經歷具體的。
        @Test
        public void activityInstanceTest() throws Exception {
            // 1 獲取核心物件
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            // 2 拿到歷史服務物件例項
            HistoryService historyService = processEngine.getHistoryService();
            // 3 拿到查詢物件
            HistoricActivityInstanceQuery activityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
            //4 設定查詢條件  執行查詢
            List<HistoricActivityInstance> list = activityInstanceQuery.processInstanceId("2505").list();
            for (HistoricActivityInstance historicActivityInstance : list) {
                System.out.println(historicActivityInstance);
            }
        }

7.7)檢視是否流程結束

    /**          * 查詢流程狀態是否結束          */         @Test         public void checkProceeEnd() throws Exception {             ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();             RuntimeService runtimeService = engine.getRuntimeService();             //建立流程查詢物件         ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery();             //查詢條件             ProcessInstanceQuery processInstanceId = query.processInstanceId("2504");             ProcessInstance result = query.singleResult();             if(result==null){                 System.out.println("processInstanceId="+processInstanceId+"流程已經結束");             }else{                 System.out.println("processInstanceId="+processInstanceId+"流程還在執行中");             }         }

8)核心API

 1. ProcessEngine: 在Activiti中最核心的類,其他的類都是由他而來,它管理著7個服務類物件

各個Service的作用:

 1. RepositoryService    管理流程規則相關。流程定義  倉庫服務類主要是管理bpmn檔案和流程圖片,可以通過核心物件獲取,和流程定義相關的操作都使用這個型別的物件實現部署流程,流程定義列表的查詢,檢視規則流程圖,刪除流程(刪除部署,流程的掛起和啟用)  2. RuntimeService    執行管理,包括啟動、推進、刪除流程例項等操作  執行時服務物件流程例項相關的操作都使用這個型別的物件實現可以啟動流程,檢視流程狀態;  3. TaskService    任務管理,比如任務的檢視、辦理等 任務服務類物件任務相關的操作要使用該物件來檢視私有任務、公共任務和認領任務、完成任務  4. HistoryService    歷史管理(執行完的資料的管理) 歷史相關的操作(主要用於檢視流程操作的歷史過程)  5. IdentityService    Activiti的組織機構管理  6. FormService    一個可選服務,任務表單管理  7. ManagerService    管理定時任務  8. RepositoryService:規則類,是Activiti的倉庫服務類  9. ProcessDefinition:定義流程物件,可以獲取到資原始檔  10. ProcessInstance:流程例項物件,每個部署就是一個流程例項  11. Execution :執行物件 一個流程中,執行物件可以存在多個,但是流程例項只能有一個。 當流程按照規則只執行一次的時候,那麼流程例項就是執行物件。