程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2EE >> jBPM4實現基本活動(上)

jBPM4實現基本活動(上)

編輯:J2EE

5.1. ActivityBehaviour

PVM庫沒有包含完整的流程結構。 作為替代的是,活動的運行時行為被委派給一個ActivityBehaviour。 換句話講,ActivityBehaviour是一個接口, 它用來在純Java環境實現流程結構的運行時行為。

  1. public interface ActivityBehaviour extends Serializable {
  2. void execute(ActivityExecution execution) throws Exception;
  3. }

當一個活動行為被調用時,它就處於執行傳播的全部控制中。 換句話說,一個活動行為可以決定下一步應該執行什麼執行。 比如,可以使用execution.take(Transition)獲得一個轉移, 或者使用execution.waitForSignal()進入等待階段。 萬一活動行為沒有調用任何上述的執行傳播方法, 執行將 按默認方式執行。

5.2. ActivityBehaviour實例

我們會啟動一個非常原始的hello world例子。 一個Display活動會將一條信息打印到控制台:

  1. public class Display implements ActivityBehaviour {
  2. String message;
  3. public Display(String message) {
  4. this.message = message;
  5. }
  6. public void execute(ActivityExecution execution) {
  7. System.out.println(message);
  8. }
  9. }

讓我們使用這個活動構建我們第一個流程定義:

Display實例流程

Display實例流程

圖 5.1. Display實例流程

TODO add ProcessBuilder example code

現在我們可以像下面這樣執行流程:

Execution execution = processDefinition.startExecution();

startExecution的調用會在控制台打印hello world:

hello
world

一個總是值得提醒的事情是活動可以使用屬性進行配置。 在Display例子中,你可以看到message屬性在兩種使用方法中配置的不同。 通過配置屬性,我們可以寫出可復用的活動。 它們可以在以後每次使用在流程中都進行不同的配置。 這是一個基本的部分, 將流程語言構建在流程虛擬機之上。

其他需要解釋的部分是 這個活動實現沒有包含任何執行傳播的功能。 當一個新流程實例啟動時, 執行會定位到初始活動,那個活動會被執行。 Display.execute方法用來決定默認的執行傳播。 具體的,這意味著活動自己 沒有調用任何執行傳播的方法。 那種情況下,默認的傳播會執行。默認傳播會選擇第一個轉移,如果這個轉移存在的話。 如果沒有,它會結束這個執行。 這揭示了為什麼a活動和b活動都被執行, 而在b活動執行完執行會停止。

關於默認流程行為的更多細節可以 在第 7.3 節 “默認執行行為”找到。

5.3. ExternalActivityBehaviour

外部活動是負責流程執行由外部轉移進來的活動, 外部的意思是來自流程系統的外部。 這意味著這個執行流程對於系統來說,這是一個等待狀態。 這個執行會一直等待到外部觸發器調用。

為了處理外部觸發器,ExternalActivityBehaviour 為ActivityBehaviour添加了一個方法:

  1. public interface ExternalActivity extends Activity {
  2. void signal(Execution execution,
  3. String signal,
  4. Map parameters) throws Exception;
  5. }

就像普通的活動,當一個執行到達一個活動, 外部活動行為的execute方法會被調用。 在外部活動中,execute方法會傳遞另一個系統的響應, 然後通過調用execution.waitForSignal() 進入等待狀態。 比如在execute方法中,響應可能是由一個人傳入, 通過在任務管理系統中創建一個任務入口, 然後等待到這個人完成這個任務。

一旦活動行為已經處於等待狀態, 然後執行會等待到調用signal方法。 執行會委派signal給ExternalActivityBehaviour對象 分配給當前的活動。

所以活動的signal方法 會在等待期間,在執行獲得一個外部觸發器的時候調用。 signal方法中,響應會傳遞給後面的流程執行。 比如,當一個人完成了一個任務,任務管理系統 會在執行中調用signal方法。

一個signal可選擇使用signal名字和一個參數map。 活動行為攔截signal和參數的最常用方式是 signal對應選擇的外出轉移, 參數作為執行中的變量。但那些只是例子, 它一直等到活動使用singal和它期望的參數。

5.4. ExternalActivity實例

這裡是一個簡單等待狀態實現的第一個例子:

  1. public class WaitState implements ExternalActivity {
  2. public void execute(ActivityExecution execution) {
  3. execution.waitForSignal();
  4. }
  5. public void signal(ActivityExecution execution,
  6. String signalName,
  7. Map parameters) {
  8. execution.take(signalName);
  9. }
  10. }

execute方法調用execution.waitForSignal()。 execution.waitForSignal()的調用 會使流程執行進入等待狀態, 直到一個外部觸發器出現。

signal方法使用signal參數對應的轉移名稱 來選擇轉移。所以當一個執行獲得一個外部觸發器, signal名稱被攔截,作為外部轉移的名稱, 執行會被傳播到那個轉移上。

這裡是從a到b有一個轉移的相同的流程。 這時候,兩個活動的行為都是WaitState。
外部活動實例流程

外部活動實例流程

圖 5.2. 外部活動實例流程

  1. ClIEntProcessDefinition processDefinition = ProcessFactory.build()
  2. .activity("a").initial().behaviour(new WaitState())
  3. .transition().to("b")
  4. .activity("b").behaviour(new WaitState())
  5. .done();

讓我們為流程定義啟動一個新流程實例:

ClIEntExecution execution = processDefinition.startProcessInstance();

啟動這個流程會執行a中的WaitState活動。 WaitState.execute會調用 ActivityExecution.waitForSignal。 所以當processDefinition.startProcessInstance()返回, 執行會一直處在a活動。

assertEquals("a", execution.getActivityName());

然後我們提供了外部觸發器, 通過調用signal方法。

execution.signal();

execution.signal()會委派給當前活動。 所以在這種情況下就是a活動裡的 WaitState活動。WaitState.signal會調用 ActivityExecution.take(String transitionName)。 當我們沒有提供一個signal名稱,第一個名字是null會被選中。 我們指定的a的唯一轉移沒有名字,所以會選中這個。 然後這個轉移指向b。 當執行到達b活動, b活動中的WaitState活動會被執行。 就像我們上面看到的,執行會在b一直等待, 這時signal會返回, 離開的執行指向b活動。

assertEquals("b", execution.getActivityName());

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved