activiti工做流(傳智播客)

1:工做流的概念css

這裏寫圖片描述 
這裏寫圖片描述

說明:

1) 假設:這兩張圖就是華誼兄弟的請假流程圖 
2) 圖的組成部分: 
A. 人物:范冰冰 馮小剛 王中軍 
B. 事件(動做):請假、批准、不批准html

這裏寫圖片描述 
這裏寫圖片描述 
工做流(Workflow),就是「業務過程的部分或總體在計算機應用環境下的自動化」,它主要解決的是「使在多個參與者之間按照某種預約義的規則傳遞文檔、信息或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現」。 
工做流管理系統(Workflow Management System, WfMS)是一個軟件系統,它完成工做量的定義和管理,並按照在系統中預先定義好的工做流規則進行工做流實例的執行。工做流管理系統不是企業的業務系統,而是爲企業的業務系統的運行提供了一個軟件的支撐環境。 
工做流管理聯盟(WfMC,Workflow Management Coalition)給出的關於工做流管理系統的定義是:工做流管理系統是一個軟件系統,它經過執行通過計算的流程定義去支持一批專門設定的業務流程。工做流管理系統被用來定義、管理、和執行工做流程。 
工做流管理系統的目標:管理工做的流程以確保工做在正確的時間被指望的人員所執行——在自動化進行的業務過程當中插入人工的執行和干預。 
3:Activiti介紹 
Activiti5是由Alfresco軟件在2010年5月17日發佈的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工做流、服務協做等領域的一個開源的、靈活的、易擴展的可執行流程語言框架。Activiti基於Apache許可的開源BPM平臺,創始人Tom Baeyens是JBoss jBPM的項目架構師,它特點是提供了eclipse插件,開發人員能夠經過插件直接繪畫出業務 
流程圖。 
這裏寫圖片描述java

3.1:工做流引擎 
ProcessEngine對象,這是Activiti工做的核心。負責生成流程運行時的各類實例及數據、監控和管理流程的運行。 
3.2:BPMN 
業務流程建模與標註(Business Process Model and Notation,BPMN) ,描述流程的基本符號,包括這些圖元如何組合成一個業務流程圖(Business Process Diagram)mysql

3.3:數據庫(先了解後看) 
Activiti數據庫支持: 
Activiti的後臺是有數據庫的支持,全部的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。 用途也和服務的API對應。 
ACT_RE_*: ‘RE’表示repository。 這個前綴的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。 
ACT_RU_*: ‘RU’表示runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。 Activiti只在流程實例執行過程當中保存這些數據, 在流程結束時就會刪除這些記錄。 這樣運行時表能夠一直很小速度很快。 
ACT_ID_*: ‘ID’表示identity。 這些表包含身份信息,好比用戶,組等等。 
ACT_HI_*: ‘HI’表示history。 這些表包含歷史數據,好比歷史流程實例, 變量,任務等等。 
ACT_GE_*: 通用數據, 用於不一樣場景下,如存放資源文件。spring

表結構操做: 
3.3.1:資源庫流程規則表 
1) act_re_deployment 部署信息表 
2) act_re_model 流程設計模型部署表 
3) act_re_procdef 流程定義數據表 
3.3.2:運行時數據庫表 
1) act_ru_execution 運行時流程執行實例表 
2) act_ru_identitylink 運行時流程人員表,主要存儲任務節點與參與者的相關信息 
3) act_ru_task 運行時任務節點表 
4) act_ru_variable 運行時流程變量數據表 
3.3.3:歷史數據庫表 
1) act_hi_actinst 歷史節點表 
2) act_hi_attachment 歷史附件表 
3) act_ih_comment 歷史意見表 
4) act_hi_identitylink 歷史流程人員表 
5) act_hi_detail 歷史詳情表,提供歷史變量的查詢 
6) act_hi_procinst 歷史流程實例表 
7) act_hi_taskinst 歷史任務實例表 
8) act_hi_varinst 歷史變量表 
3.3.4:組織機構表 
1) act_id_group 用戶組信息表 
2) act_id_info 用戶擴展信息表 
3) act_id_membership 用戶與用戶組對應信息表 
4) act_id_user 用戶信息表 
這四張表很常見,基本的組織機構管理,關於用戶認證方面建議仍是本身開發一套,組件自帶的功能太簡單,使用中有不少需求難以知足 
3.3.5:通用數據表 
1) act_ge_bytearray 二進制數據表 
2) act_ge_property 屬性數據表存儲整個流程引擎級別的數據,初始化表結構時,會默認插入三條記錄, 
3.4:activiti.cfg.xml(activiti的配置文件) 
Activiti核心配置文件,配置流程引擎建立工具的基本參數和數據庫鏈接池參數。 
定義數據庫配置參數: 
 jdbcUrl: 數據庫的JDBC URL。 
 jdbcDriver: 對應不一樣數據庫類型的驅動。 
 jdbcUsername: 鏈接數據庫的用戶名。 
 jdbcPassword: 鏈接數據庫的密碼。 
基於JDBC參數配置的數據庫鏈接 會使用默認的MyBatis鏈接池。 下面的參數能夠用來配置鏈接池(來自MyBatis參數): 
 jdbcMaxActiveConnections: 鏈接池中處於被使用狀態的鏈接的最大值。默認爲10。 
 jdbcMaxIdleConnections: 鏈接池中處於空閒狀態的鏈接的最大值。 
 jdbcMaxCheckoutTime: 鏈接被取出使用的最長時間,超過期間會被強制回收。 默認爲20000(20秒)。 
 jdbcMaxWaitTime: 這是一個底層配置,讓鏈接池能夠在長時間沒法得到鏈接時, 打印一條日誌,並從新嘗試獲取一個鏈接。(避免由於錯誤配置致使沉默的操做失敗)。 默認爲20000(20秒)。 
示例數據庫配置: 
這裏寫圖片描述sql

也可使用javax.sql.DataSource。 (好比,Apache Commons的DBCP): 
這裏寫圖片描述 
3.5:logging.properties(日誌處理) 
日誌的配置文件,Activiti操做數據庫的時候,整合的日誌文件 
4:準備環境 
4.1:activiti5 軟件環境 
1) JDK1.6或者更高版本 
2) 支持的數據庫有:h2, mysql, oracle, postgres, mssql, db2等。 
3) 支持activiti5運行的jar包 
4) 開發環境爲Eclipse3.7或者以上版本,myeclipse爲8.6版本 
4.2:相關資源下載 
1) JDK能夠到sun的官網下載 
http://www.oracle.com/technetwork/java/javase/downloads/index.html 
2) 數據庫,例如:mysql能夠在官網上下載。 
http://www.mysql.com 
3) activiti也能夠到Activiti官方網站下載獲得。 
http://activiti.org/download.html 
4) Eclipse3.7或者MyEclipse8.6也能夠到相應的網站上得到下載。 
4.3:安裝流程設計器(eclipse插件) 
4.3.1:安裝方式一 
在有網絡的狀況下,安裝流程設計器步驟以下: 
1) 打開 Help -> Install New Software. 在以下面板中: 
這裏寫圖片描述
2) 在以下Install界面板中,點擊Add按鈕: 
這裏寫圖片描述 
配置新裝插件的地址和名稱數據庫

3) 而後填入下列字段 
Name: Activiti BPMN 2.0 designer 
Location: http://activiti.org/designer/update/ 
這裏寫圖片描述 
4) 回到Install界面,在面板正中列表中把全部展現出來的項目都勾上: 
這裏寫圖片描述 
5) 點擊複選框 
在Detail部分記得選中 「Contact all updates sites..」 , 由於它會檢查全部當前安裝所須要的插件並能夠被Eclipse下載.編程

6) 安裝完之後,點擊新建工程new->Other…打開面板,若是看到下圖內容: 
這裏寫圖片描述 
說明安裝成功了。 
4.3.2:安裝方式二 
在沒有網絡的狀況下,安裝流程設計器步驟以下: 
1) 解壓老師發給你們的 壓縮包 
2) 把壓縮包中的內容放入eclipse根目錄的dropins文件夾下 
3) 重啓eclipse,點擊新建工程new->Other…打開面板,若是看到下圖內容: 
這裏寫圖片描述 
說明安裝成功了 
4.4:對流程設計器的使用說明 
打開菜單Windows->Preferences->Activiti->Save下流程流程圖片的生成方式: 
這裏寫圖片描述 
雖然流程引擎在單獨部署bpmn文件時會自動生成圖片,但在實際開發過程當中,自動生成的圖片會致使和BPMN中的座標有出入,在實際項目中展現流程當前位置圖會有問題。 
所在完成以上配置後,會由咱們本身來管理流程圖片。在發佈流程時把流程規則文件和流程圖片一塊兒上傳就好了。 
4.5:準備Activiti5開發環境 
4.5.1:添加Activiti5的jar包 
在activiti-5.13->wars目錄下是一些示例項目,解壓activiti-rest項目,導入activiti-rest目錄中WEB-INF\lib下全部包。添加到classpath中。 
因爲咱們使用的是Mysql數據庫,Mysql數據庫的連接驅動Activiti官方包中並無提供,須要咱們本身導入。手動導入mysql-connector-java.jar,添加到classpath下。 
4.5.2:初始化數據庫 
這裏寫圖片描述
在Activiti中,在建立核心的流程引擎對象時會自動建表。若是程序正常執行,mysql會自動建庫,而後建立23張表。緩存

4.5.3:添加並制定配置文件 
在Actiiti5中定製流程一定會操做到數據庫,若是都像上面那樣寫一大段代碼會很是麻煩,因此咱們能夠把數據庫鏈接配置寫入配置文件。 
在Activiti5的官方示例中並無現成的配置文件,因此先得找到activiti-rest\WEB-INF\classes下有:網絡

4.5.3.1:activiti-context.xml : 
一個相似spring結構的配置文件,清空內容後更名爲activiti.cfg.xml,用來作流程引擎的相關配置。 
按照上面代碼配置ProcessEngineConfiguration對象,主要定義數據庫的鏈接配置和建表策略,配置文件代碼以下: 
這裏寫圖片描述
Java代碼以下: 
這裏寫圖片描述
createProcessEngineConfigurationFromResource的參數值爲咱們添加的配置文件activiti.cfg.xml的名稱,執行java代碼,流程引擎對象建立成功運行後數據庫會自動建表。

/**使用代碼建立工做流須要的23張表*/ @Test public void createTable(){ ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); //鏈接數據庫的配置 processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver"); processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/shareniu?useUnicode=true&characterEncoding=utf8"); processEngineConfiguration.setJdbcUsername("root"); processEngineConfiguration.setJdbcPassword("root"); /** public static final String DB_SCHEMA_UPDATE_FALSE = "false";不能自動建立表,須要表存在 public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先刪除表再建立表 public static final String DB_SCHEMA_UPDATE_TRUE = "true";若是表不存在,自動建立表 */ processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //工做流的核心對象,ProcessEnginee對象 ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine(); System.out.println("processEngine:"+processEngine); } /**使用配置文件建立工做流須要的23張表*/ @Test public void createTable_2(){ // ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml"); // //工做流的核心對象,ProcessEnginee對象 // ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine(); ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml") // .buildProcessEngine(); System.out.println("processEngine:"+processEngine); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4.5.3.2:log4j.properties 日誌配置文件 
把兩個文件放入resource目錄下便可。

5:核心API 
5.1:ProcessEngine 
說明: 
1) 在Activiti中最核心的類,其餘的類都是由他而來。 
2) 產生方式:

在前面看到了兩種建立ProcessEngine(流程引擎)的方式,而這裏要簡化不少,調用ProcessEngines的getDefaultProceeEngine方法時會自動加載classpath下名爲activiti.cfg.xml文件。 
3) 能夠產生RepositoryService

4) 能夠產生RuntimeService

5) 能夠產生TaskService

各個Service的做用: 
RepositoryService 管理流程定義 
RuntimeService 執行管理,包括啓動、推動、刪除流程實例等操做 
TaskService 任務管理 
HistoryService 歷史管理(執行完的數據的管理) 
IdentityService 組織機構管理 
FormService 一個可選服務,任務表單管理 
ManagerService

5.2:RepositoryService 
是Activiti的倉庫服務類。所謂的倉庫指流程定義文檔的兩個文件:bpmn文件和流程圖片。 
1) 產生方式

2) 能夠產生DeploymentBuilder,用來定義流程部署的相關參數

3) 刪除流程定義

5.3:RuntimeService 
是activiti的流程執行服務類。能夠從這個服務類中獲取不少關於流程執行相關的信息。 
5.4:TaskService 
是activiti的任務服務類。能夠從這個類中獲取任務的信息。 
5.5:HistoryService 
是activiti的查詢歷史信息的類。在一個流程執行完成後,這個對象爲咱們提供查詢歷史信息。 
5.6:ProcessDefinition 
流程定義類。能夠從這裏得到資源文件等。 
5.7:ProcessInstance 
表明流程定義的執行實例。如范冰冰請了一天的假,她就必須發出一個流程實例的申請。一個流程實例包括了全部的運行節點。咱們能夠利用這個對象來了解當前流程實例的進度等信息。流程實例就表示一個流程從開始到結束的最大的流程分支,即一個流程中流程實例只有一個。 
5.8:Execution 
Activiti用這個對象去描述流程執行的每個節點。在沒有併發的狀況下,Execution就是同ProcessInstance。流程按照流程定義的規則執行一次的過程,就能夠表示執行對象Execution。 
如圖爲ProcessInstance的源代碼: 
這裏寫圖片描述
從源代碼中能夠看出ProcessInstance就是Execution。但在現實意義上有所區別: 
這裏寫圖片描述 
在單線流程中,如上圖的貸款流程,ProcessInstance與Execution是一致的。 
這裏寫圖片描述 
這個例子有一個特色:wire money(匯錢)和archive(存檔)是併發執行的。 這個時候,總線路表明ProcessInstance,而分線路中每一個活動表明Execution。 
總結: 
* 一個流程中,執行對象能夠存在多個,可是流程實例只能有一個。 
* 當流程按照規則只執行一次的時候,那麼流程實例就是執行對象。

6:HelloWorld程序(模擬流程的執行) 
6.1:流程圖:

這裏寫圖片描述 
6.2:部署流程定義 
這裏寫圖片描述 
這裏使用RepositoryService部署流程定義 
addClasspathResource表示從類路徑下加載資源文件,一次只能加載一個文件 
6.3:啓動流程實例 
這裏寫圖片描述 
這裏使用RuntimeService啓動流程實例 
6.4:查看個人我的任務 
這裏寫圖片描述 
這裏使用TaskService完成任務的查詢 
6.5:完成個人我的任務 
這裏寫圖片描述 
這裏使用TaskService完成任務的辦理

7:管理流程定義 
7.1:設計流程定義文檔 
7.1.1:流程圖 
這裏寫圖片描述 
7.1.2:bpmn文件 
BPMN 2.0根節點是definitions節點。 這個元素中,能夠定義多個流程定義(不過咱們建議每一個文件只包含一個流程定義, 能夠簡化開發過程當中的維護難度)。 一個空的流程定義看起來像下面這樣。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的聲明。 targetNamespace能夠是任意值,它用來對流程實例進行分類。 
這裏寫圖片描述 
說明:流程定義文檔有兩部分組成: 
1) bpmn文件 
流程規則文件。在部署後,每次系統啓動時都會被解析,把內容封裝成流程定義放入項目緩存中。Activiti框架結合這個xml文件自動管理流程,流程的執行就是按照bpmn文件定義的規則執行的,bpmn文件是給計算機執行用的。 
2) 展現流程圖的圖片 
在系統裏須要展現流程的進展圖片,圖片是給用戶看的。

7.2:部署流程定義(classpath路徑加載文件) 
這裏寫圖片描述 
說明: 
1) 先獲取流程引擎對象:在建立時會自動加載classpath下的activiti.cfg.xml

2) 首先得到默認的流程引擎,經過流程引擎獲取了一個RepositoryService對象(倉庫對象) 
3) 由倉庫的服務對象產生一個部署對象配置對象,用來封裝部署操做的相關配置。 
4) 這是一個鏈式編程,在部署配置對象中設置顯示名,上傳流程定義規則文件 
5) 向數據庫表中存放流程定義的規則信息。 
6) 這一步在數據庫中將操做三張表: 
a) act_re_deployment(部署對象表) 
存放流程定義的顯示名和部署時間,每部署一次增長一條記錄。 
這裏寫圖片描述 
這裏寫圖片描述
Deployment deployment = processEngine.getRepositoryService()// 
.createDeployment().name(「入門程序」)// 
.addClasspathResource(「hello/helloworld.bpmn」)// 從classpath的資源中加載,一次只能加載一個文件 
// .addClasspathResource(「diagrams/helloworld.png」)// 
// 從classpath的資源中加載,一次只能加載一個文件 
.deploy(); 
b) act_re_procdef(流程定義表) 
存放流程定義的屬性信息,部署每一個新的流程定義都會在這張表中增長一條記錄。 
注意:當流程定義的key相同的狀況下,使用的是版本升級 
這裏寫圖片描述 
這裏寫圖片描述
對應的封裝類:

public interface ProcessDefinition {

  String getId(); String getCategory(); String getName(); String getKey(); String getDescription(); int getVersion(); String getResourceName(); String getDeploymentId(); String getDiagramResourceName(); boolean hasStartFormKey(); boolean isSuspended(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

代碼的操做: 
/* 查詢流程定義 /

@Test public void findProcessDefinition() { List<ProcessDefinition> list = processEngine.getRepositoryService()// 與流程定義和部署對象相關的Service .createProcessDefinitionQuery()// 建立一個流程定義的查詢 /** 指定查詢條件,where條件 */ // .deploymentId(deploymentId)//使用部署對象ID查詢 // .processDefinitionId(processDefinitionId)//使用流程定義ID查詢 // .processDefinitionKey(processDefinitionKey)//使用流程定義的key查詢 // .processDefinitionNameLike(processDefinitionNameLike)//使用流程定義的名稱模糊查詢 /** 排序 */ .orderByProcessDefinitionVersion().asc()// 按照版本的升序排列 // .orderByProcessDefinitionName().desc()//按照流程定義的名稱降序排列 /** 返回的結果集 */ .list();// 返回一個集合列表,封裝流程定義 // .singleResult();//返回唯一結果集 // .count();//返回結果集數量 // .listPage(firstResult, maxResults);//分頁查詢 if (list != null && list.size() > 0) { for (ProcessDefinition pd : list) { System.out.println("流程定義ID:" + pd.getId());// 流程定義的key+版本+隨機生成數 System.out.println("流程定義的名稱:" + pd.getName());// 對應helloworld.bpmn文件中的name屬性值 System.out.println("流程定義的key:" + pd.getKey());// 對應helloworld.bpmn文件中的id屬性值 System.out.println("流程定義的版本:" + pd.getVersion());// 當流程定義的key值相同的相同下,版本升級,默認1 System.out.println("資源名稱bpmn文件:" + pd.getResourceName()); System.out.println("資源名稱png文件:" + pd.getDiagramResourceName()); System.out.println("部署對象ID:" + pd.getDeploymentId()); System.out .println("#########################################################"); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

程序的輸出: 
流程定義ID:helloworld:1:4 
流程定義的名稱:helloworldProcess 
流程定義的key:helloworld 
流程定義的版本:1 
資源名稱bpmn文件:hello/helloworld.bpmn 
資源名稱png文件:hello/helloworld.helloworld.png 
部署對象ID:1 
c) act_ge_bytearray(資源文件表) 
存儲流程定義相關的部署信息。即流程定義文檔的存放地。每部署一次就會增長兩條記錄,一條是關於bpmn規則文件的,一條是圖片的(若是部署時只指定了bpmn一個文件,activiti會在部署時解析bpmn文件內容自動生成流程圖)。兩個文件不是很大,都是以二進制形式存儲在數據庫中。 
這裏寫圖片描述
7.3:部署流程定義(zip格式文件) 
這裏寫圖片描述 
這裏寫圖片描述 
將 
壓縮成zip格式的文件,使用zip的輸入流用做部署流程定義

7.4:查看流程定義 
查詢流程定義的信息 
這裏寫圖片描述 
結果: 
這裏寫圖片描述 
再部署一次運行結果爲: 
這裏寫圖片描述 
能夠看到流程定義的key值相同的狀況下,版本是從1開始逐次升級的 
流程定義的Id是【key:版本:生成ID】 
說明: 
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表生成 
這裏寫圖片描述 
7.5:刪除流程定義 
刪除部署到activiti中的流程定義。 
這裏寫圖片描述 
說明: 
1) 由於刪除的是流程定義,而流程定義的部署是屬於倉庫服務的,因此應該先獲得RepositoryService 
2) 若是該流程定義下沒有正在運行的流程,則能夠用普通刪除。若是是有關聯的信息,用級聯刪除。項目開發中使用級聯刪除的狀況比較多,刪除操做通常只開放給超級管理員使用。 
7.6:獲取流程定義文檔的資源(查看流程圖附件) 
查詢出流程定義文檔。主要查的是圖片,用於顯示流程用。 
這裏寫圖片描述 
說明: 
1) deploymentId爲流程部署ID 
2) resourceName爲act_ge_bytearray表中NAME_列的值 
3) 使用repositoryService的getDeploymentResourceNames方法能夠獲取指定部署下得全部文件的名稱 
4) 使用repositoryService的getResourceAsStream方法傳入部署ID和資源圖片名稱能夠獲取部署下指定名稱文件的輸入流 
5) 最後的有關IO流的操做,使用FileUtils工具的copyInputStreamToFile方法完成流程流程到文件的拷貝,將資源文件以流的形式輸出到指定文件夾下 
7.7:附加功能:查詢最新版本的流程定義 
這裏寫圖片描述 
Key value保存 key 爲key value爲流程定義 
代碼: 
/*附加功能:查詢最新版本的流程定義*/

@Test
    public void findLastVersionProcessDefinition(){
        List<ProcessDefinition> list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .orderByProcessDefinitionVersion().asc()//使用流程定義的版本升序排列 .list(); /** * Map<String,ProcessDefinition> map集合的key:流程定義的key map集合的value:流程定義的對象 map集合的特色:當map集合key值相同的狀況下,後一次的值將替換前一次的值 */ Map<String, ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>(); if(list!=null && list.size()>0){ for(ProcessDefinition pd:list){ map.put(pd.getKey(), pd); } } List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values()); if(pdList!=null && pdList.size()>0){ for(ProcessDefinition pd:pdList){ System.out.println("流程定義ID:"+pd.getId());//流程定義的key+版本+隨機生成數 System.out.println("流程定義的名稱:"+pd.getName());//對應helloworld.bpmn文件中的name屬性值 System.out.println("流程定義的key:"+pd.getKey());//對應helloworld.bpmn文件中的id屬性值 System.out.println("流程定義的版本:"+pd.getVersion());//當流程定義的key值相同的相同下,版本升級,默認1 System.out.println("資源名稱bpmn文件:"+pd.getResourceName()); System.out.println("資源名稱png文件:"+pd.getDiagramResourceName()); System.out.println("部署對象ID:"+pd.getDeploymentId()); System.out.println("#########################################################"); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

7.8:附加功能:刪除流程定義(刪除key相同的全部不一樣版本的流程定義) 
這裏寫圖片描述

@Test
    public void deleteProcessDefinitionByKey() { // 流程定義的key String processDefinitionKey = "helloworld"; // 先使用流程定義的key查詢流程定義,查詢出全部的版本 List<ProcessDefinition> list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .processDefinitionKey(processDefinitionKey).list();// // 遍歷,獲取每一個流程定義的部署ID if (list != null && list.size() > 0) { for(ProcessDefinition pd:list){ //獲取部署ID String deploymentId = pd.getDeploymentId(); processEngine.getRepositoryService()// .deleteDeployment(deploymentId, true); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

7.9:總結 
Deployment 部署對象 
一、一次部署的多個文件的信息。對於不須要的流程能夠刪除和修改。 
二、對應的表: 
act_re_deployment:部署對象表 
act_re_procdef:流程定義表 
act_ge_bytearray:資源文件表 
act_ge_property:主鍵生成策略表

ProcessDefinition 流程定義 
一、解析.bpmn後獲得的流程定義規則的信息,工做流系統就是按照流程定義的規則執行的。

8:流程實例、任務的執行 
8.1:流程圖 
這裏寫圖片描述 
8.2:部署流程定義 
這裏寫圖片描述 
8.3:啓動流程實例 
這裏寫圖片描述
說明: 
1) 操做數據庫的act_ru_execution表,若是是用戶任務節點,同時也會在act_ru_task添加一條記錄 
act_ru_execution表,#正在執行的執行對象表 任務結束的以前只有 一個 變化的字段是act_id 
這裏寫圖片描述
這裏寫圖片描述

8.4:查詢個人我的任務 
這裏寫圖片描述

@Test public void findMyPersonalTask(){ String assignee = "王五"; List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service .createTaskQuery()//建立任務查詢對象 /**查詢條件(where部分)*/ .taskAssignee(assignee)//指定我的任務查詢,指定辦理人 // .taskCandidateUser(candidateUser)//組任務的辦理人查詢 // .processDefinitionId(processDefinitionId)//使用流程定義ID查詢 // .processInstanceId(processInstanceId)//使用流程實例ID查詢 // .executionId(executionId)//使用執行對象ID查詢 /**排序*/ .orderByTaskCreateTime().asc()//使用建立時間的升序排列 /**返回結果集*/ // .singleResult()//返回唯一結果集 // .count()//返回結果集的數量 // .listPage(firstResult, maxResults);//分頁查詢 .list();//返回列表 if(list!=null && list.size()>0){ for(Task task:list){ 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.getProcessInstanceId()); System.out.println("執行對象ID:"+task.getExecutionId()); System.out.println("流程定義ID:"+task.getProcessDefinitionId()); System.out.println("########################################################"); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

輸出: 
任務ID:504 
任務名稱:提交申請 
任務的建立時間:Sat Aug 09 08:50:20 CST 2014 
任務的辦理人:張三 
流程實例ID:501 
執行對象ID:501 
流程定義ID:helloworld:1:404 
接口:

public interface Task { int DEFAULT_PRIORITY = 50; String getId(); String getName(); void setName(String name); String getDescription(); void setDescription(String description); int getPriority(); void setPriority(int priority); String getOwner(); void setOwner(String owner); String getAssignee(); void setAssignee(String assignee); DelegationState getDelegationState(); void setDelegationState(DelegationState delegationState); String getProcessInstanceId(); String getExecutionId(); String getProcessDefinitionId(); Date getCreateTime(); String getTaskDefinitionKey(); Date getDueDate(); void setDueDate(Date dueDate); void delegate(String userId); void setParentTaskId(String parentTaskId); String getParentTaskId(); boolean isSuspended(); Map<String, Object> getTaskLocalVariables(); Map<String, Object> getProcessVariables(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

說明: 
1) 由於是任務查詢,因此從processEngine中應該獲得TaskService 
2) 使用TaskService獲取到任務查詢對象TaskQuery 
3) 爲查詢對象添加查詢過濾條件,使用taskAssignee指定任務的辦理者(即查詢指定用戶的代辦任務),同時能夠添加分頁排序等過濾條件 
4) 調用list方法執行查詢,返回辦理者爲指定用戶的任務列表 
5) 任務ID、名稱、辦理人、建立時間能夠從act_ru_task表中查到。 
6) Execution與ProcessInstance見5.6和5.7章節的介紹。在這種狀況下,ProcessInstance至關於Execution 
7) 若是assignee屬性爲部門經理,結果爲空。由於如今流程只到了」填寫請假申請」階段,後面的任務尚未執行,即在數據庫中沒有部門經理能夠辦理的任務,因此查詢不到。 
8) 一個Task節點和Execution節點是1對1的狀況,在task對象中使用Execution_來表示他們之間的關係 
9) 任務ID在數據庫表act_ru_task中對應「ID_」列

附加: 
在activiti任務中,主要分爲兩大類查詢任務(我的任務和組任務): 
1.確切指定了辦理者的任務,這個任務將成爲指定者的私有任務,即我的任務。 
2.沒法指定具體的某一我的來辦理的任務,能夠把任務分配給幾我的或者一到 多個小組,讓這個範圍內的用戶能夠選擇性(若有空餘時間時)來辦理這類任務,即組任務。 
先知道我的任務的查詢和辦理,組任務的操做後面講

8.5:辦理任務 
這裏寫圖片描述

說明: 
1) 是辦理任務,因此從ProcessEngine獲得的是TaskService。 
2) 當執行完這段代碼,再以員工的身份去執行查詢的時候,會發現這個時候已經沒有數據了,由於正在執行的任務中沒有數據。 
3) 對於執行完的任務,activiti將從act_ru_task表中刪除該任務,下一個任務會被插入進來。 
4) 以」部門經理」的身份進行查詢,能夠查到結果。由於流程執行到部門經理審批這個節點了。 
5) 再執行辦理任務代碼,執行完之後以」部門經理」身份進行查詢,沒有結果。 
6) 重複第3和4步直到流程執行完。 
act_ru_task表: 
這裏寫圖片描述

8.6:查詢流程狀態(判斷流程正在執行,仍是結束) 
這裏寫圖片描述 
/* 查詢流程狀態(判斷流程正在執行,仍是結束) /

@Test
    public void isProcessEnd() { String processInstanceId = "501"; ProcessInstance pi = processEngine.getRuntimeService()// 表示正在執行的流程實例和執行對象 .createProcessInstanceQuery()// 建立流程實例查詢 .processInstanceId(processInstanceId)// 使用流程實例ID查詢 .singleResult(); if (pi == null) { System.out.println("流程已經結束"); } else { System.out.println("流程沒有結束"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
在流程執行的過程當中,建立的流程實例ID在整個過程當中都不會變,當流程結束後,流程實例將會在正在執行的執行對象表中(act_ru_execution)被刪除
說明:

1) 由於是查詢流程實例,因此先獲取runtimeService 
2) 建立流程實例查詢對象,設置實例ID過濾參數 
3) 因爲一個流程實例ID只對應一個實例,使用singleResult執行查詢返回一個惟一的結果,若是結果數量大於1,則拋出異常 
4) 判斷指定ID的實例是否存在,若是結果爲空,則表明流程結束,實例在正在執行的執行對象表中已被刪除,轉換成歷史數據。 
8.7:附加功能:查詢歷史任務(後面講) 
這裏寫圖片描述 
/*查詢歷史任務(後面講)/

@Test
    public void findHistoryTask(){
        String taskAssignee = "張三"; List<HistoricTaskInstance> list = processEngine.getHistoryService()//與歷史數據(歷史表)相關的Service .createHistoricTaskInstanceQuery()//建立歷史任務實例查詢 .taskAssignee(taskAssignee)//指定歷史任務的辦理人 .list(); if(list!=null && list.size()>0){ for(HistoricTaskInstance hti:list){ System.out.println(hti.getId()+" "+hti.getName()+" "+hti.getProcessInstanceId()+" "+hti.getStartTime()+" "+hti.getEndTime()+" "+hti.getDurationInMillis()); System.out.println("################################"); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

表《HistoricTaskInstance》 
8.8:附加功能:查詢歷史流程實例(後面講)

這裏寫圖片描述 
8.9:總結 
Execution 執行對象 
按流程定義的規則執行一次的過程. 
對應的表: 
act_ru_execution: 正在執行的信息 
act_hi_procinst:已經執行完的歷史流程實例信息 
act_hi_actinst:存放歷史全部完成的活動 
ProcessInstance 流程實例 
特指流程從開始到結束的那個最大的執行分支,一個執行的流程中,流程實例只有1個。

注意 
(1)若是是單例流程,執行對象ID就是流程實例ID 
(2)若是一個流程有分支和聚合,那麼執行對象ID和流程實例ID就不相同 
(3)一個流程中,流程實例只有1個,執行對象能夠存在多個。

Task 任務 
執行到某任務環節時生成的任務信息。 
對應的表: 
act_ru_task:正在執行的任務信息 
act_hi_taskinst:已經執行完的歷史任務信息

9:流程變量 
9.1:流程圖 
這裏寫圖片描述 
流程變量在整個工做流中扮演很重要的做用。例如:請假流程中有請假天數、請假緣由等一些參數都爲流程變量的範圍。流程變量的做用域範圍是只對應一個流程實例。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成之後流程變量還保存在數據庫中。 
例如: 
這裏寫圖片描述
即:

9.2:部署流程定義 
這裏寫圖片描述 
說明: 
• 輸入流加載資源文件的3種方式 
這裏寫圖片描述 
這裏寫圖片描述

9.3:啓動流程實例 
這裏寫圖片描述 
9.4:設置流程變量 
這裏寫圖片描述
說明: 
1) 流程變量的做用域就是流程實例,因此只要設置就好了,不用管在哪一個階段設置 
2) 基本類型設置流程變量,在taskService中使用任務ID,定義流程變量的名稱,設置流程變量的值。 
3) Javabean類型設置流程變量,須要這個javabean實現了Serializable接口 
4) 設置流程變量的時候,向act_ru_variable這個表添加數據

9.5:獲取流程變量 
這裏寫圖片描述

說明: 
1) 流程變量的獲取針對流程實例(即1個流程),每一個流程實例獲取的流程變量時不一樣的 
2) 使用基本類型獲取流程變量,在taskService中使用任務ID,流程變量的名稱,獲取流程變量的值。 
3) Javabean類型設置獲取流程變量,除了須要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,不然拋出異常。 
解決方案,在javabean對象中添加: 
private static final long serialVersionUID = 6757393795687480331L; 
9.6:模擬流程變量的設置和獲取的場景 
這裏寫圖片描述 
說明: 
1) RuntimeService對象能夠設置流程變量和獲取流程變量 
2) TaskService對象能夠設置流程變量和獲取流程變量 
3) 流程實例啓動的時候能夠設置流程變量 
4) 任務辦理完成的時候能夠設置流程變量 
5) 流程變量能夠經過名稱/值的形式設置單個流程變量 
6) 流程變量能夠經過Map集合,同時設置多個流程變量 
Map集合的key表示流程變量的名稱 
Map集合的value表示流程變量的值

9.7:查詢歷史的流程變量 
這裏寫圖片描述 
說明: 
1)歷史的流程變量查詢,指定流程變量的名稱,查詢act_hi_varinst表(也能夠針對,流程實例ID,執行對象ID,任務ID查詢)

9.8:流程變量的支持的類型 
如圖是從官網列出來的流程變量的類型: 
這裏寫圖片描述 
從圖中能夠看出包括了大部分封裝類型和Date、String和實現了Serializable接口的類的類型。 
9.9:總結 
• 1:流程變量 
在流程執行或者任務執行的過程當中,用於設置和獲取變量,使用流程變量在流程傳遞的過程當中傳遞業務參數。 
對應的表: 
act_ru_variable:正在執行的流程變量表 
act_hi_varinst:流程變量歷史表

• 2:擴展知識:setVariable和setVariableLocal的區別 
setVariable:設置流程變量的時候,流程變量名稱相同的時候,後一次的值替換前一次的值,並且能夠看到TASK_ID的字段不會存聽任務ID的值 
setVariableLocal: 
1:設置流程變量的時候,針對當前活動的節點設置流程變量,若是一個流程中存在2個活動節點,對每一個活動節點都設置流程變量,即便流程變量的名稱相同,後一次的版本的值也不會替換前一次版本的值,它會使用不一樣的任務ID做爲標識,存放2個流程變量值,並且能夠看到TASK_ID的字段會存聽任務ID的值 
例如act_hi_varinst 表的數據:不一樣的任務節點,即便流程變量名稱相同,存放的值也是不一樣的。 
如圖: 
這裏寫圖片描述
2:還有,使用setVariableLocal說明流程變量綁定了當前的任務,當流程繼續執行時,下個任務獲取不到這個流程變量(由於正在執行的流程變量中沒有這個數據),全部查詢正在執行的任務時不能查詢到咱們須要的數據,此時須要查詢歷史的流程變量。

10:流程執行歷史記錄 
10.1:查詢歷史流程實例 
查找按照某個流程定義的規則一共執行了多少次流程 
這裏寫圖片描述 
10.2:查詢歷史活動 
某一次流程的執行一共經歷了多少個活動 
這裏寫圖片描述 
10.3:查詢歷史任務 
某一次流程的執行一共經歷了多少個任務 
這裏寫圖片描述 
10.4:查詢歷史流程變量 
某一次流程的執行一共設置的流程變量 
這裏寫圖片描述  10.5:總結  因爲數據庫中保存着歷史信息以及正在運行的流程實例信息,在實際項目中對已完成任務的查看頻率遠不及對代辦和可接任務的查看,因此在activiti採用分開管理,把正在運行的交給RuntimeService、TaskService管理,而歷史數據交給HistoryService來管理。  這樣作的好處在於,加快流程執行的速度,由於正在執行的流程的表中數據不會很大

相關文章
相關標籤/搜索