1. 程式人生 > >activiti入門3排他閘道器,並行網管,包括閘道器,事件閘道器

activiti入門3排他閘道器,並行網管,包括閘道器,事件閘道器

文章轉載於:http://www.cnblogs.com/yxysuanfa/p/7261306.html

閘道器用來控制流程的流向 閘道器能夠消費也能夠生成token。

閘道器顯示成菱形圖形,內部有有一個小圖示。 圖標表示閘道器的型別。

基本分支

首先 利用 流程變數  寫個帶有分支的一個基本流程

流程圖:




部署流程檔案:

//獲取流程引擎
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	@Test
	public void deployFlow(){
		
		//獲取倉庫服務物件
		RepositoryService repositoryService = processEngine.getRepositoryService();
		
		InputStream in = this.getClass().getResourceAsStream("/MyProcess11.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in);
		
		Deployment dm = repositoryService.createDeployment()
											.name("學生請假")
											.addZipInputStream(zipInputStream)
											.deploy();
		
		System.out.println("id:"+dm.getId()+",name:"+dm.getName());
	}
啟動流程 並 設定請假天數為 3天的 流程變數 提交 

/**
	 * 啟動流程 並完畢 提交
	 */
	@Test
	public void startProcessAndComp(){
		
		RuntimeService runtimeService = processEngine.getRuntimeService();
		ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave");
		
		System.out.println("id:"+pi.getId()+",流程例項ID:"+pi.getProcessInstanceId()+",流程定義ID:"+pi.getProcessDefinitionId());
		
		TaskService taskService = processEngine.getTaskService();
		
		//通過流程例項ID獲取任務物件
		Task task = taskService.createTaskQuery()
							.processInstanceId(pi.getProcessInstanceId())
							.singleResult();
		System.out.println("taskID:"+task.getId()+",name:"+task.getName());
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		//設定流程變數day=3
		paramMap.put("day", 3);
		//提交任務的時候傳入流程變數
		taskService.complete(task.getId(), paramMap);
		
		//查詢任務
		task = taskService.createTaskQuery()
				.processInstanceId(pi.getProcessInstanceId())
				.singleResult();
		
		//假設任務物件為空,則流程執行結束
		if (task != null) {
			System.out.println("taskID:"+task.getId()+",name:"+task.getName());
		} else {
			System.out.println("任務執行完畢");
		}
	}

最後的執行結果:

id:1501,流程例項ID:1501,流程定義ID:leave:2:1404
taskID:1504,name:班主任
任務執行完成

我們能夠再資料庫中檢視:





我們部署一個 流程檔案 , 而且在提交 任務的時候 設定流程變數 請假天數為 10天


最後的執行結果

id:1701,流程例項ID:1701,流程定義ID:leave:3:1604
taskID:1704,name:班主任
taskID:1707,name:年級主任

如今 流程就到了另外 一條線


年紀主任審批通過:

	/**
	 * 提交任務
	 */
	@Test
	public void completeTask(){
		TaskService taskService = processEngine.getTaskService();
		taskService.complete("1707");
	}

流程執行結束

                                                                                                                                                                                                                                                                    

排他閘道器:

排他閘道器描寫敘述

排他閘道器(也叫異或(XOR)閘道器,或更技術性的叫法 基於資料的排他閘道器), 用來在流程中實現決策。 當流程執行到這個閘道器,全部外出順序流都會被處理一遍。 當中條件解析為true的順序流(或者沒有設定條件,概念上在順序流上定義了一個'true') 會被選中,讓流程繼續執行。

注意這裡的外出順序流 與BPMN 2.0通常的概念是不同的。

通常情況下,全部條件結果為true的順序流 都會被選中。以並行方式執行。但排他閘道器僅僅會選擇一條順序流執行。 就是說,儘管多個順序流的條件結果為true。 那麼XML中的第一個順序流(也僅僅有這一條)會被選中,並用來繼續執行流程。

假設沒有選中不論什麼順序流。會丟擲一個異常。

排他閘道器圖形

排他閘道器顯示成一個普通閘道器(比方。菱形圖形), 內部是一個“X”圖示,表示異或(XOR)語義。

注意。沒有內部圖示的閘道器,默覺得排他閘道器。 BPMN 2.0規範不同意在同一個流程定義中同一時候使用沒有X和有X的菱形圖形。

流程檔案:



排他閘道器有個預設的選項  default flow ,  當 default flow 設定後  就不用設定表示式了,  假設全部的條件都不通過 就會執行預設的流程


年級主任審批和校長審批



首先 還是 先把檔案部署 

//獲取流程引擎
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	@Test
	public void deployFlow2(){
		
		//獲取倉庫服務物件
		RepositoryService repositoryService = processEngine.getRepositoryService();
		
		InputStream in = this.getClass().getResourceAsStream("/exclusiveGateway.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in);
		
		Deployment dm = repositoryService.createDeployment()
											.name("學生請假")
											.addZipInputStream(zipInputStream)
											.deploy();
		
		System.out.println("id:"+dm.getId()+",name:"+dm.getName());
	}


啟動流程, 並提交 設定 請假天數 為 10天   結果

id:2001,流程例項ID:2001,流程定義ID:exclusiveGateWay:1:1904
taskID:2004,name:學生請假
taskID:2008,name:年級主任審批

再 又一次部署一個流程檔案 然後啟動 提交  設定請假天數為 30天 執行結果

id:2201,name:學生請假
id:2301,流程例項ID:2301,流程定義ID:exclusiveGateWay:2:2204
taskID:2304,name:學生請假
taskID:2308,name:校長審批
最後在 部署一遍, 這次設定請假天數為 3天  結果

id:2501,name:學生請假
id:2601,流程例項ID:2601,流程定義ID:exclusiveGateWay:3:2504
taskID:2604,name:學生請假
taskID:2608,name:班主任審批

這裡 流程走到了 當初 預設的設定  班主任審批



當我們設定了 預設 的 配置  ,即使沒有 設定表示式  流程 條件都 不滿足的時候  都會執行預設的

並行閘道器

並行閘道器描寫敘述

閘道器也能夠表示流程中的並行情況。最簡單的並行閘道器是 並行閘道器,它同意將流程 成多條分支。也能夠把多條分支 到一起。 of execution.

並行閘道器的功能是基於進入和外出的順序流的:

  • 分支: 並行後的全部外出順序流,為每一個順序流都建立一個併發分支。

  • 匯聚: 全部到達並行閘道器。在此等待的進入分支。 直到全部進入順序流的分支都到達以後。 流程就會通過匯聚閘道器。

注意。假設同一個並行閘道器有多個進入和多個外出順序流。 它就同一時候具有分支和匯聚功能。 這時。閘道器會先匯聚全部進入的順序流,然後再切分成多個並行分支。

與其它閘道器的主要差別是,並行閘道器不會解析條件。

即使順序流中定義了條件。也會被忽略。

並行閘道器圖形

並行閘道器顯示成一個普通閘道器(菱形)內部是一個“加號”圖示, 表示“與(AND)”語義。

首先 畫一個簡單的並行流程



注意  並行 閘道器 要有2個  一個是用於 分支  一個用於 聚合

部署啟動

@Test
	public void deployFlow3() {

		// 獲取倉庫服務物件
		RepositoryService repositoryService = processEngine
				.getRepositoryService();

		InputStream in = this.getClass().getResourceAsStream("/Parallel.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in);

		Deployment dm = repositoryService.createDeployment().name("並行閘道器")
				.addZipInputStream(zipInputStream).deploy();

		System.out.println("id:" + dm.getId() + ",name:" + dm.getName());

		RuntimeService runtimeService = processEngine.getRuntimeService();
		ProcessInstance pi = runtimeService
				.startProcessInstanceByKey("parallel");

		System.out.println("id:" + pi.getId() + ",流程例項ID:"
				+ pi.getProcessInstanceId() + ",流程定義ID:"
				+ pi.getProcessDefinitionId());

	}


id:2801,name:並行閘道器
id:2901,流程例項ID:2901,流程定義ID:parallel:1:2804
此時流程進入  啟動專案環節   通過流程例項ID 檢視當前流程 進度

/**
	 * 啟動流程 並完畢 提交
	 */
	@Test
	public void startProcessAndComp3() {

		TaskService taskService = processEngine.getTaskService();

		// 查詢任務
		Task task = taskService.createTaskQuery().processInstanceId("2901").singleResult();

		// 假設任務物件為空,則流程執行結束
		if (task != null) {
			System.out.println("taskID:" + task.getId() + ",name:"
					+ task.getName());
		} else {
			System.out.println("任務執行完畢");
		}

		// 通過流程例項ID獲取任務物件
		task = taskService.createTaskQuery().processInstanceId("2901").singleResult();
		System.out.println("taskID:" + task.getId() + ",name:" + task.getName());

		// 提交任務
		taskService.complete(task.getId());

	}
taskID:2904,name:專案啟動
taskID:2904,name:專案啟動
提交任務後,流程進入並行環節,同一時候執行 功能模組1 和 功能模組2


這是我們能夠看到  流程例項ID 和 執行物件ID 已經是不同了

這個是 act_ru_execution 表的資料 


我們先 提交一個  功能模組1的任務 

在看 任務表  act_ru_task 


此時 任務表 僅僅有 功能模組2 

我們在看  act_ru_execution  這個表  依然是3條資料  功能模組1 的執行流程 被堵塞在   並行閘道器這裡  沒有進入 測試公佈這個 環節


在提交功能模組2  任務

檢視 這  2個表



流程 已經 進入 下一個環節 

提交最後一個人  整個流程結束,  我們在檢視  歷史活動表  act_hi_actinst


整個流程 分成了 2 塊



包括閘道器

包括閘道器描寫敘述

包括閘道器能夠看做是排他閘道器和並行閘道器的結合體。 和排他閘道器一樣,你能夠在外出順序流上定義條件。包括閘道器會解析它們。 可是基本的差別是包括閘道器能夠選擇多於一條順序流。這和並行閘道器一樣。

包括閘道器的功能是基於進入和外出順序流的:

  • 分支: 全部外出順序流的條件都會被解析。結果為true的順序流會以並行方式繼續執行。 會為每一個順序流建立一個分支。

  • 匯聚: 全部並行分支到達包括閘道器。會進入等待章臺, 直到每一個包括流程token的進入順序流的分支都到達。 這是與並行閘道器的最大不同。換句話說,包括閘道器僅僅會等待被選中運行了的進入順序流。 在匯聚之後,流程會穿過包括閘道器繼續執行。

注意,假設同一個包括節點擁有多個進入和外出順序流。 它就會同一時候含有分支和匯聚功能

這時,閘道器會先匯聚全部擁有流程token的進入順序流。 再依據條件推斷結果為true的外出順序流,為它們生成多條並行分支。

包括閘道器圖形

並行閘道器顯示為一個普通閘道器(菱形),內部包括一個圓圈圖示。


當 main config 中的 表示式 條件返回的結果為真時  執行 並行閘道器 

結果為假時 執行 排他任務

詳細的 流程 這裡就不介紹了


事件閘道器

事件閘道器描寫敘述

基於事件網關同意依據事件推斷流向。

閘道器的每一個外出順序流都要連線到一箇中間捕獲事件。 當流程到達一個基於事件閘道器,閘道器會進入等待狀態:會暫停執行。 與此同一時候,會為每一個外出順序流建立相對的事件訂閱。

注意基於事件閘道器的外出順序流和普通順序流不同。這些順序流不會真的"執行"。

相反。它們讓流程引擎去決定執行到基於事件閘道器的流程須要訂閱哪些事件。

要考慮下面條件:

  • 基於事件閘道器必須有兩條或以上外出順序流。

  • 基於事件閘道器後,僅僅能使用intermediateCatchEvent型別。 (activiti不支援基於事件閘道器後連線ReceiveTask。)

  • 連線到基於事件閘道器的intermediateCatchEvent僅僅能有一條進入順序流。

事件閘道器圖形

事件閘道器和其它BPMN閘道器一樣顯示成一個菱形, 內部包括指定圖示。