<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 26,comments - 77,trackbacks - 0
    5.5. 基本流程執行

    在下一個例子里,我們會結合自動活動和等待狀態。 這里例子構建了貸款審批流程,使用WaitState 和Display活動,我們剛剛創建的。 貸款流程的圖形看起來像這樣:
    貸款流程



    圖 5.3. 貸款流程

    使用Java構建流程圖形是很乏味的事情, 因為你必須在局部變量中跟蹤所有的引用。 為了解決這個問題,流程虛擬機提供了一個ProcessFactory。 ProcessFactory是一種領域特定語言(DSL),可以嵌入到Java中, 簡化流程圖形的結構。這個模型也叫做 流暢接口。

    ClientProcessDefinition processDefinition = ProcessFactory.build("loan")
      .activity("submit loan request").initial().behaviour(new Display("loan request submitted"))
        .transition().to("evaluate")
      .activity("evaluate").behaviour(new WaitState())
        .transition("approve").to("wire money")
        .transition("reject").to("end")
      .activity("wire money").behaviour(new Display("wire the money"))
        .transition().to("archive")
      .activity("archive").behaviour(new WaitState())
        .transition().to("end")
      .activity("end").behaviour(new WaitState())
    .done();

    為了了解ProcessFactory的更多細節,可以參考 api文檔。 ProcessFactory的另一種選擇是創建一個XML語言和一個XML解析器,來表示流程。 XML解析器可以直接實例化 org.jbpm.pvm.internal.model包中的類。 這種方式一般都被流程語言選擇使用。

    初始化活動submit loan request和 wire the money活動是自動活動。 在這個例子中,wire the money活動的 Display實現 使用Java API來把信息輸出到控制臺上。但是讀取器可以想象一個可選的 Activity實現,使用支付流程庫的Java API 來實現一個真實的自動支付。

    上述流程的一個新執行可以像下面這樣啟動

    ClientExecution execution = processDefinition.startProcessInstance();

    當startExecution方法返回時, submit loan request活動會被執行, 執行會位于evaluate活動。
    位于'evaluate'活動的執行



    圖 5.4. 位于'evaluate'活動的執行

    現在,執行處在一個很有趣的點。這里有兩個轉移從evaluate指向外邊。 一個轉移叫approve 一個轉移叫reject。像我們上面解釋的, WaitState實現會根據執行的signal選擇轉移。 讓我們像這樣執行'approve' signal:

    execution.signal("approve");

    這個approve signal會導致執行選擇approve轉移 它會到達wire money活動。

    在wire money活動中,信息會打印到控制臺里。 因為Display沒有調用execution.waitForSignal(), 也沒有調用其他執行傳播方法, 默認流程行為只會讓執行繼續, 使用向外的轉移到達archive活動, 這也是一個WaitState。
    位于'archive'活動的執行



    圖 5.5. 位于'archive'活動的執行

    所以只有當archive到達時, signal("approve")會返回。

    另一個signal就像這樣:

    execution.signal("approve");

    將讓執行最終到達結束狀態。
    位于'end'活動的執行



    圖 5.6. 位于'end'活動的執行

    5.6. 事件

    事件位于流程定義中, 一系列的EventListener可以進行注冊。

    public interface EventListener extends Serializable {

      void notify(EventListenerExecution execution) throws Exception;

    }

    事件的目的是讓開發者可以為流程添加程序邏輯, 不必改變流程圖。 這是非常有價值的機制,可以促進業務分析人員和開發者之間的協作。 業務分析人員負責描述需求。 當他們使用流程圖歸檔那些需求, 開發者可以獲得這些圖形,讓它可執行化。 事件會非常方便,向一個流程中添加技術細節(比如一些數據庫插入操作) 這些都是業務分析人員不感興趣的東西。

    最常用的事件是由執行自動觸發的:

    TODO: 在用戶手冊中解釋事件

    事件是由流程元素和事件名稱結合而成。 用戶和流程語言也可以出發事件, 使用編程的方式在流程中使用fire方法。

    public interface Execution extends Serializable {
      ...
      void fire(String eventName, ProcessElement eventSource);
      ...
    }

    可以把一系列的EventListeners分配給一個事件。 但是事件監聽器不能控制執行的流向, 因為它們僅僅是監聽已經執行了的執行。 這與活動處理活動的行為是不同的。 活動行為可以響應執行的傳播。

    我們會創建一個PrintLn事件監聽器, 這與上面的Display活動是非常相似的。

    public class PrintLn implements EventListener {

      String message;

      public PrintLn(String message) {
        this.message = message;
      }

      public void notify(EventListenerExecution execution) throws Exception {
        System.out.println("message");
      }
    }

    多個PrintLn監聽器 會在流程中注冊。
    PrintLn監聽器流程



    圖 5.7. PrintLn監聽器流程

    ClientProcessDefinition processDefinition = ProcessFactory.build()
      .activity("a").initial().behaviour(new AutomaticActivity())
        .event("end")
          .listener(new PrintLn("leaving a"))
          .listener(new PrintLn("second message while leaving a"))
        .transition().to("b")
          .listener(new PrintLn("taking transition"))
      .activity("b").behaviour(new WaitState())
        .event("start")
          .listener(new PrintLn("entering b"))
    .done();

    第一個事件演示如何為相同的事件注冊多個監聽器。 它們會根據它們指定的順序依次執行。

    然后,在轉椅上,這里的事件只有一種類型。 所以在那種情況下,事件類型不需要指定, 監聽器可以直接添加到轉移上。

    一個監聽器每次都會執行,當一個執行觸發事件時,如果這個監聽器被注冊了。 執行會作為一個參數提供給活動接口, 除了控制流程傳播的方法以外, 都可以被監聽器使用。
    5.7. 事件傳播

    事件會默認傳播給最近的流程元素。 目的是允許監聽器在流程定義或組合活動中 可以執行所有發生在流程元素中的事件。 比如這個功能允許為end事件在流程定義或一個組合活動中注冊一個事件監聽器。 這種動作會被執行,如果一個活動離開。 如果事件監聽器被注冊到一個組合活動中, 它也會被所有活動執行,當組合活動中出現了離開事件。

    為了清楚地顯示這個,我們會創建一個DisplaySource事件監聽器, 這會把leaving信息和事件源 打印到控制臺。

    public class DisplaySource implements EventListener {

      public void execute(EventListenerExecution execution) {
        System.out.println("leaving "+execution.getEventSource());
      }
    }

    注意事件監聽器的目的不是可視化,這是為什么事件監聽器本身 不應該顯示在圖形中。一個DisplaySource事件監聽器 會作為end事件的監聽器添加到組合活動中。

    下一個流程展示了DisplaySource事件監聽器如何 作為'end'事件的監聽器注冊到composite活動:
    一個在組合活動中為end事件注冊了不可見的事件監聽器的流程。



    圖 5.8. 一個在組合活動中為end事件注冊了不可見的事件監聽器的流程。

    TODO 更新代碼片段

    下一步,我們會啟動一個執行。

    ClientExecution execution = processDefinition.startProcessInstance();

    在啟動一個新執行后,執行將在a活動中 作為初始活動。沒有活動離開,所以沒有信息被記錄下來。 下一個signal會給與執行, 導致它選擇從a到b。

    execution.signal();

    當signal方法返回,執行會選擇轉移 然后end事件會被a活動觸發。 那個組合活動會被傳播到組合活動和流程定義中。 因為我們的DisplaySource 監聽器放到 composite活動中, 它會接收事件,把下面的信息打印到控制臺中:

    leaving activity(a)

    另一個

    execution.signal();

    會選擇b到c的轉移。那會觸發兩個活動離開事件。 一個在b活動,一個在組合活動。 所以下面的幾行會添加到控制臺輸出中:

    leaving activity(b)
    leaving activity(composite)

    事件傳播建立在流程定義的繼承組合結構中。 頂級元素總是流程定義。 流程定義包含一系列活動。每個活動可以是葉子活動或者可以是一個組合節點, 這意味著它包含了一系列內嵌活動。 內嵌活動可以被使用,比如超級狀態或組合活動,在內嵌流程語言中,像BPEL。

    所以事件模型在組合活動和上面的流程定義中的功能是相似的。 想象'Phase one'模型一個超級狀態作為一個狀態機。 然后事件傳播允許在超級狀態中注冊所有事件。 這個主意是繼承組合響應圖形展示。 如果一個'e'元素畫在另一個'p'元素中, 'p'是'e'的父節點。一個流程定義擁有一系列定義活動。 每個活動可以擁有一系列內嵌活動。 一個轉移的父節點就是它的源頭和目的的第一個父節點。

    如果一個事件監聽器對傳播的事件沒有興趣, 可以在構建流程使用ProcessFactory的propagationDisabled()。 下一個流程是與上面相同的流程, 除了傳播的事件會被事件監聽器禁用。 圖形還是一樣。
    注冊到'end'事件的事件監聽器被禁用的流程。



    圖 5.9. 注冊到'end'事件的事件監聽器被禁用的流程。

    使用流程工廠構建流程:

    TODO 更新代碼

    所以當第一個signal在流程中調用時,end事件 會再次觸發在a活動上,但是現在在組合活動的事件監聽器 不會被執行,因為傳播的事件被禁用了。 禁用傳播是單獨的事件監聽器的一個屬性, 不會影響其他監聽器。事件會一直被觸發, 傳播到整個父繼承結構。

    ClientExecution execution = processDefinition.startProcessInstance();

    第一個signal會選擇從a到b的流程。 沒有信息會被打印到控制臺。

    execution.signal();

    下一步,第二個signal會選擇從b到c的轉移。

    execution.signal()

    還是兩個end事件被觸發, 就像上面分別在b和composite活動中。 第一個事件是b活動上的 end事件。 那將被傳播給composite活動。 所以事件監聽器不會為這個事件執行,因為它已經禁用了傳播。 但是事件監聽器會在composite活動上 為end事件執行。 那是不傳播的,但是直接在composite活動上觸發。 所以事件監聽器現在會被執行 一次,為組合活動,就像下面控制臺里顯示的那樣:

    leaving activity(composite)


    jBPM4.0中文開發指南完整版http://family168.com/tutorial/jbpm4devguide/html/index.html
    posted on 2009-06-25 17:38 卡宴 閱讀(950) 評論(0)  編輯  收藏 所屬分類: jBPM
    主站蜘蛛池模板: 亚洲精彩视频在线观看| 9277手机在线视频观看免费| 亚洲一区在线视频观看| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 亚洲欧美在线x视频| 亚洲视屏在线观看| 亚洲精品V欧洲精品V日韩精品| 日本特黄特色免费大片| 97性无码区免费| 99精品视频免费观看| 91国内免费在线视频| 美女黄色免费网站| 亚洲国产精品自在自线观看| 亚洲一区二区三区精品视频| 亚洲天天做日日做天天看| 亚洲精品美女久久777777| 亚洲精品国产精品乱码不卡| 国产又长又粗又爽免费视频| 成人免费网站在线观看| 波多野结衣中文字幕免费视频| 久久综合给合久久国产免费| 日韩电影免费在线观看中文字幕| 72pao国产成视频永久免费| 日产久久强奸免费的看| 国产精品久久久久久亚洲小说 | 99久久久国产精品免费无卡顿| 久久久久高潮毛片免费全部播放| 18禁超污无遮挡无码免费网站| 久久精品无码免费不卡| 一级特黄录像视频免费| 人妖系列免费网站观看| 无码日韩人妻AV一区免费l| 一级毛片免费不卡直观看| 一级日本高清视频免费观看| 一区二区三区免费精品视频 | 国产亚洲AV夜间福利香蕉149| 国产精品亚洲综合一区| 自拍偷自拍亚洲精品被多人伦好爽 | 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 国产成人精品免费视频大| 日韩不卡免费视频|