Activiti學習筆記四 流程定義的管理(一)

上一篇模擬了流程執行,這一篇來看下流程定義的管理。

1.設計流程定義文檔

  • 流程圖

  • BPMN文件

        BPMN 2.0根節點是definitions節點。 這個元素中,可以定義多個流程定義(不過建議每個文件只包含一個流程定義, 這樣可以簡化開發過程中的維護難度)。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的聲明。 targetNamespace可以是任意值,它用來對流程實例進行分類。

 

說明:流程定義文檔由兩部分組成:

        1)bpmn文件

              流程規則文件。在部署後,每次系統啓動時都會被解析,把內容封裝成流程定義放入項目緩存中。Activiti框架結合這個xml文件自動管理流程,流程的執行就是按照bpmn文件定義的規則執行的,bpmn文件是給系統執行用的

        2)流程圖的png圖片

              在系統裏需要展示流程的進展狀況,圖片是給用戶看的

2.部署流程定義(classpath路徑加載)

    private final ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    /**
     * 功能: 部署流程定義classpath.<br/>
     * date: 2014年12月16日 下午1:02:11 <br/>
     * 
     * @author [email protected]
     */
    @Test
    public void deploymentProcessDefinitionByClassPath() {
        Deployment deployment = processEngine.getRepositoryService()
                // 與流程定義和部署相關的Service
                .createDeployment()
                // 創建部署對象
                .name("流程定義")
                // 部署名稱
                .addClasspathResource("diagrams/helloworld.bpmn").addClasspathResource("diagrams/helloworld.png")
                .deploy(); // 部署
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名稱:" + deployment.getName());
    }


   說明:

         1)先獲取流程引擎對象:在創建時會自動加載classpath下的activiti.cfg.xml。

         2)通過流程引擎獲取了一個RepositoryService對象(倉庫服務對象)。

         3)由倉庫的服務對象產生一個部署對象配置對象,用來封裝部署操作的相關配置。

         4)在部署配置對象中設置顯示名,上傳流程定義規則文件。

         5) 向數據庫表中存放流程定義的規則信息。

  添加操作設計到數據庫中的三張表:

         1. act_re_deployment(部署對象表)

            存放流程定義的名稱和部署時間,每部署一次增加一條記錄。

          

        2.act_re_procdef(流程定義表)

存放流程定義的屬性信息,部署每個新的流程定義都會在這張表中增加一條記錄。

注意:當流程定義的key相同的情況下,使用的是版本升級。

       3.act_ge_bytearray(資源文件表)

            存儲流程定義相關的部署信息。即流程定義文檔的存放地。每部署一次就會增加兩條記錄,一條是關於bpmn規則文件的,一條是圖片的(如果部署時只指定了bpmn一個文件,activiti會在部署時解析bpmn文件內容自動生成流程圖)。兩個文件不是很大,都是以二進制形式存儲在數據庫中。

          

         4. act_ge_property (主鍵生成策略表) (順帶提下)

           這是一張主鍵生成策略表。

          

2.部署流程定義(zip格式文件)

          首先將兩個流程定義文檔helloworld.bpmn和helloworld.png打包爲zip格式的文件放到resource目錄,使用zip的輸入流部署流程定義。

         

/**
     * 功能: 部署流程定義zip.<br/>
     * date: 2014年12月16日 下午2:09:03 <br/>
     * 
     * @author [email protected]
     */
    @Test
    public void deploymentProcessDefinitionByZip() {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deployment = processEngine.getRepositoryService()
        // 與流程定義和部署相關的Service
                .createDeployment()
                // 創建部署對象
                .name("流程定義")
                // 部署名稱
                .addZipInputStream(zipInputStream) // 指定zip文件
                .deploy(); // 部署
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名稱:" + deployment.getName());
    }


3.查看流程定義

/**
     * 功能: 流程定義的查詢.<br/>
     * date: 2014年12月16日 下午2:58:21 <br/>
     * 
     * @author [email protected]
     */
    @Test
    public void queryProcessDefinition() {
        List<ProcessDefinition> list = processEngine.getRepositoryService()// 與流程定義和部署對象相關Service
                .createProcessDefinitionQuery() // 創建流程定義查詢
                // .deploymentId(deploymentId) 使用部署對象Id查詢
                // .processDefinitionId(processDefinitionId) 使用流程定義Id查詢
                // .processDefinitionKey(processDefinitionKey) 使用流程定義key查詢
                // .processDefinitionNameLike(processDefinitionNameLike)
                // 使用流程定義名稱模糊查詢 ...
                /** 排序 */
                // .orderByProcessDefinitionVersion().asc() 按照版本的升序排列
                // .orderByProcessDefinitionName().desc() 按照流程定義名稱降序排列
                // .singleResult(); 返回唯一結果集
                // .count() 返回記錄數
                // .listPage(firstResult, maxResults) 分頁查詢
                .list();// 返回集合
        if (null != list && list.size() > 0) {
            for (ProcessDefinition pd : list) {
                System.out.println("流程定義ID:" + pd.getId()); // key + 版本 + 隨機數
                System.out.println("流程定義的名稱:" + pd.getName()); // 對應bpmn文件中Name屬性
                System.out.println("流程定義的key:" + pd.getKey()); // 對應bpmn文件中ID屬性
                System.out.println("流程定義的版本:" + pd.getVersion()); // 當流程定義的key值相同下,版本升級,默認是1
                System.out.println("部署對象的ID:" + pd.getDeploymentId());
                System.out.println("資源文件bpmn名稱:" + pd.getResourceName());
                System.out.println("資源文件png名稱:" + pd.getDiagramResourceName());
                System.out.println("############################################");
            }
        }
    }

 

說明:

        1)流程定義和部署對象相關的Service都是RepositoryService。

        2)創建流程定義查詢對象,可以在ProcessDefinitionQuery上設置查詢的相關參數。

        3)調用ProcessDefinitionQuery對象的list方法,執行查詢,獲得符合條件的流程定義列表。

        4)由運行結果可以看出Key和Name的值爲:bpmn文件process節點的id和name的屬性值

      5)key屬性被用來區別不同的流程定義。

      6)帶有特定key的流程定義第一次部署時,version爲1。之後每次部署都會在當前最高版本號上加1。

      7)Id的值的生成規則爲:{processDefinitionKey}:{processDefinitionVersion}:{generated-id},這裏的generated-id是一個自動生成的唯一的數字。

      8)重新部署一次,deploymentId的值是由規則變化的,具體規則由act_ge_property表生成。

4.刪除流程定義

/**
     * 功能: 刪除流程定義.<br/>
     * date: 2014年12月16日 下午3:41:06 <br/>
     * 
     * @author [email protected]
     */
    @Test
    public void deleteProcessDefinition() {
        // 使用部署Id刪除
        String deploymentId = "901";
        // 不帶級聯刪除,只能刪除沒有啓動的流程,流程啓動則拋出異常
        // processEngine.getRepositoryService().deleteDeployment(deploymentId);
        // 級聯刪除,會刪除該流程所有相關的信息,包括歷史信息
        processEngine.getRepositoryService().deleteDeployment(deploymentId, true);
        System.out.println("刪除成功!");
    }


說明:

        1)刪除流程定義首先獲取RepositoryService。

        2)如果該流程定義下沒有正在運行的流程,則可以用普通刪除。如果是有關聯的信息,用級聯刪除。實際項目開發中使用級聯刪除的情況比較多,刪除操作一般只開放給超級管理員使用。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章