上一篇模擬了流程執行,這一篇來看下流程定義的管理。
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)如果該流程定義下沒有正在運行的流程,則可以用普通刪除。如果是有關聯的信息,用級聯刪除。實際項目開發中使用級聯刪除的情況比較多,刪除操作一般只開放給超級管理員使用。