溫馨提示:您的每一次轉載,體現了我寫此文的意義!!!煩請您在轉載時注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          雪山飛鵠

          溫馨提示:您的每一次轉載,體現了我寫此文的意義!!!煩請您在轉載時注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            215 Posts :: 1 Stories :: 674 Comments :: 0 Trackbacks

          本文電子版文檔下載
          State
          、Decision 、Task活動詳解:

          State表示一個等待狀態。當流程實例執行到state節點時會暫停下來(處于等待狀態),流程的執行會在外部觸發器被調用之前一直等待(會暫停)

          Decision條件判斷節點,表示在多條路徑中選擇一條。一個 decision 活動擁有很多個傳出的轉移。流程的執行到達一個 decision 活動時,會自動進行計算來決定采用哪個傳出的轉移(滿足條件時,向下執行,沒有符合條件時會停留在decision活動的上一個活動)

          Task任務組件,主要用來為流程實例分配任務。通常與form表單相關聯.(會暫停下來)

          State節點示例

          無分支的state節點

          流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="demo" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="134,113,48,48" name="start">

                <transition g="-53,-17" name="to state" to="state"/>

             </start>

             <state g="219,204,92,52" name="state">

                <transition g="-41,-17" name="to end" to="end"/>

             </state>

             <end g="329,301,48,48" name="end"/>

          </process>

          測試代碼:

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                  System.out.println("流程實例Id:"+processInstance.getId());

                  System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());

                  //判斷當前是否位于start節點

                  System.out.println("是否位于start節點:"+processInstance.isActive("start"));//false

                  //判斷當前是否位于state節點

                  System.out.println("是否位于state節點:"+processInstance.isActive("state"));//true

                  //判斷流程是否結束

                  System.out.println("判斷流程是否結束:"+processInstance.isEnded());//false

                  System.out.println("------------------------>使流程繼續向下執行");

                  //使流程繼續向下執行

                  //ProcessInstance instanceState=executionService.signalExecutionById(processInstance.getId());

                  //此處也可以這么寫

                  ProcessInstance instanceState=executionService.signalExecutionById(processInstance.getId(),"to end");

                  //to end為流程定義中用于連接state和end節點之間transition的name屬性的值

                  //判斷當前是否位于state節點

                  System.out.println("是否位于state節點:"+instanceState.isActive("state"));//false

                  //判斷流程是否結束

                  System.out.println("判斷流程是否結束:"+instanceState.isEnded());//true

          執行結果:

          流程實例Id:demo.7

          流程定義Id:demo-1

          是否位于start節點:false

          是否位于state節點:true

          判斷流程是否結束:false

          ------------------------>使流程繼續向下執行

          是否位于state節點:false

          判斷流程是否結束:true

          有分支的state節點:

          注意:在此流程定義中在state節點后含有2個分支(2個transition 即to 400和to 200),那么在使流程實例從state節點向下執行的時候需要明確給出transition的方向name屬性的值,否則流程實例會一直處于state節點

          executionService.signalExecutionById(processInstance.getId(), "to 200");

          流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="demo" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="347,27,48,48" name="start">

                <transition g="-53,-17" name="to state" to="state"/>

             </start>

             <state g="329,132,92,52" name="state">

                <transition name="to 200" to="200" g="-41,-17"/>

                <transition name="to 400" to="400" g="-41,-17"/>

             </state>

             <end g="358,321,48,48" name="end"/>

             <state name="200" g="420,226,92,52">

                <transition name="to end" to="end" g="-41,-17"/>

             </state>

             <state name="400" g="266,225,92,52">

                <transition name="to end" to="end" g="-41,-17"/>

             </state>

          </process>

          測試代碼:

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                  System.out.println("------------------------>使流程繼續向下執行");

                  System.out.println("------------------------>使流程流向200");

                  ProcessInstance processInstance200=executionService.signalExecutionById(processInstance.getId(), "to 200");

                  System.out.println("當前流程是否位于200節點---->"+processInstance200.isActive("200"));//true

                  System.out.println("當前流程是否結束---->"+processInstance200.isEnded());//false

                  /*System.out.println("------------------------>使流程流向400");

                  ProcessInstance processInstance400=executionService.signalExecutionById(processInstance.getId(), "to 400");

                  System.out.println("當前流程是否位于400節點---->"+processInstance400.isActive("400"));

                  System.out.println("當前流程是否結束---->"+processInstance400.isEnded());*/

          執行結果:

          ------------------------>使流程繼續向下執行

          ------------------------>使流程流向200

          當前流程是否位于200節點---->true

          當前流程是否結束---->false

          流向400的自己測試

          由于流程定義中200和400均為state節點,所以流程在流經200或400節點后仍會停留在該節點,以下代碼完成流程實例從start->200->end這一過程

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                  //查詢該流程實例的活動節點

                  System.out.println(processInstance.findActiveActivityNames());

                  //因為流程實例啟動后,它會自動向下執行,直到遇到state或task等節點時暫停下來,在我們的流程定義文件中緊跟在start后的節點為state,所以流程實例會在state節點暫停下來

                  Execution execution=processInstance.findActiveExecutionIn("state");//查詢當前流程實例的當前節點

                  ProcessInstance processInstance200=executionService.signalExecutionById(execution.getId(), "to 200");//此時流程流向200

                  System.out.println("當前流程是否位于200節點---->"+processInstance200.isActive("200"));//true

                  System.out.println("當前流程是否結束---->"+processInstance200.isEnded());//false

                  //使流程繼續向下執行(結束)

                  System.out.println("-------使流程繼續向下執行(結束)------->");

                  //由于200節點后沒有分支僅有end這一節點,所以200與end之間transition的name屬性的值可以省略,當然加上更好

                  ProcessInstance instance=executionService.signalExecutionById(processInstance200.getId());//流程執行到end,結束流程實例

                  System.out.println("當前流程是否結束---->"+instance.isEnded());//true

          執行結果:

          [state]

          當前流程是否位于200節點---->true

          當前流程是否結束---->false

          -------使流程繼續向下執行(結束)------->

          當前流程是否結束---->true

          Decision節點示例

          流程圖:

          流程定義:

          在使用Decision時,一個Decision活動應配置為以下三種中的一種

          decision 會檢查每一個傳出的轉移里的內置條件。流程的執行會采用第一個內置條件為

          true 或者沒有設置內置條件的轉移

          第一種:使用Decision內置條件(返回true或false)

              即在流程定義中設置每一個transition的子節點condition,并為每一個condition填充expr屬性

          形如:

          <condition expr="${coder=='200'}"></condition>

          詳細的流程定義

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="decision" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="61,51,48,48" name="開始">

                <transition g="-47,-17" name="to waite" to="waite"/>

             </start>

             <decision g="188,160,48,48" name="gowhere">

                <transition g="-41,-17" name="to 200" to="200">

                 <condition expr="${coder=='200'}"></condition>

                </transition>

                <transition g="-41,-17" name="to 500" to="500">

                 <condition expr="${coder=='500'}"></condition>

                </transition>

                <transition g="-41,-17" name="to 404" to="404">

                 <condition expr="${coder=='404'}"></condition>

                </transition>

             </decision>

             <state g="386,143,92,52" name="200">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="296,261,92,52" name="500">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="197,389,92,52" name="404">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <end g="498,407,48,48" name="結束"/>

             <state g="114,97,92,52" name="waite">

                <transition g="-65,-17" name="to gowhere" to="gowhere"/>

             </state>

          </process>

          觀察紅色標注的部分

          測試代碼:

          Map<String, String> map=new HashMap<String, String>();

                  //coder為流程定義中表達式的名稱

                  map.put("coder", "200");

                  ProcessInstance processInstance=executionService.startProcessInstanceByKey("decision",map);

                  System.out.println("流程是否處于waite節點?"+processInstance.isActive("waite"));//true

                  ProcessInstance processInstanceDecision=executionService.signalExecutionById(processInstance.getId());

                  System.out.println("流程是否處于waite節點?"+processInstanceDecision.isActive("waite"));//false

                  System.out.println("流程是否處于gowhere節點?"+processInstanceDecision.isActive("gowhere"));//false

                  System.out.println("流程是否處于200節點?"+processInstanceDecision.isActive("200"));//true

                  System.out.println("流程是否處于404節點?"+processInstanceDecision.isActive("404"));//false

                  System.out.println("流程是否處于500節點?"+processInstanceDecision.isActive("500"));//false

          代碼說明:

          在一開始定義了一個Map,在程序中手動為coder(詳見流程定義中的condition的expr屬性)賦值200,當流程實例啟動時運行到decision時會自動計算每一個transition節點子節點condition里面的expr屬性(詳見流程定義中),如果某一內置條件(condition)執行為true,則就將流程執行到該節點。在使用此種方式時, condition的expr中設置的下一活動的活動名稱(name),而不是transition的name屬性.這里緊跟在decision活動后有三個活動200、404、500且三個活動名稱依次為200、404、500,所以程序中為coder賦值200就表示將流程執行到200這個活動.

          執行結果:

          流程是否處于waite節點?true

          流程是否處于waite節點?false

          流程是否處于gowhere節點?false

          流程是否處于200節點?true

          流程是否處于404節點?false

          流程是否處于500節點?false

          第二種:為流程定義中decision活動設置expr屬性,decision 表達式返回類型為字符串的向外轉移的名字,使用此種方式不用再去為每一個transition設置condition子節點

          形如:

          <decision g="188,160,48,48" name="gowhere" expr="${towhere}">

          這里towhere就表示流程流經decision活動后要流經的下一個transition的name屬性的值

          詳細的流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="decision" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="61,51,48,48" name="開始">

                <transition g="-47,-17" name="to waite" to="waite"/>

             </start>

             <decision g="188,160,48,48" name="gowhere" expr="${towhere}">

                <transition g="-41,-17" name="to 200" to="200">

                </transition>

                <transition g="-41,-17" name="to 500" to="500">

                </transition>

                <transition g="-41,-17" name="to 404" to="404">

                </transition>

             </decision>

             <state g="386,143,92,52" name="200">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="296,261,92,52" name="500">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="197,389,92,52" name="404">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <end g="498,407,48,48" name="結束"/>

             <state g="114,97,92,52" name="waite">

                <transition g="-65,-17" name="to gowhere" to="gowhere"/>

             </state>

          </process>

          重點關注紅色標注的地方

          執行代碼:

          Map<String, String> map=new HashMap<String, String>();

                  // towhere為流程定義中表達式的名稱

                  map.put("towhere", "to 200");

                  ProcessInstance processInstance=executionService.startProcessInstanceByKey("decision",map);

                  System.out.println("流程是否處于waite節點?"+processInstance.isActive("waite"));//true

                  ProcessInstance processInstanceDecision=executionService.signalExecutionById(processInstance.getId());

                  System.out.println("流程是否處于waite節點?"+processInstanceDecision.isActive("waite"));//false

                  System.out.println("流程是否處于gowhere節點?"+processInstanceDecision.isActive("gowhere"));//false

                  System.out.println("流程是否處于200節點?"+processInstanceDecision.isActive("200"));//true

                  System.out.println("流程是否處于404節點?"+processInstanceDecision.isActive("404"));//false

                  System.out.println("流程是否處于500節點?"+processInstanceDecision.isActive("500"));//false

          代碼解釋:

          從流程圖中我們可以看出decision后有三個transition,且每個transition的name屬性的值依次為to 200、to 404、to 500.在代碼中聲明了一Map對象,并為該Map添加一個以towhere作為鍵to 200位置的元素,然后使流程向下執行.那么當流程實例流經decision活動時,會計算decision節點expr的值,從中選擇下一個transition的名稱,然后向下執行.

          使用此種方式為decision節點設置expr屬性,設置的是下一個transition的name屬性,請與第一種情況加以區別(第一種情況設置的下一活動的name)

          執行結果:

          流程是否處于waite節點?true

          流程是否處于waite節點?false

          流程是否處于gowhere節點?false

          流程是否處于200節點?true

          流程是否處于404節點?false

          流程是否處于500節點?false

          第三種:為decision配置一個handler的類(在流程定義中在decision節點內部配置<handler/>子節點,并設置該元素的class屬性為你自己的類)該類實現了org.jbpm.api.jpdl.DecisionHandler.你需要賦寫

          String decide(OpenExecution execution);方法即可,在該方法最終返回decision活動后的下一個transition的name屬性的值

          形如:

          <handler class="com.jbpm.decision.handler.HandlerDecision"></handler>

          這里class="com.jbpm.decision.handler.HandlerDecision"就表示實現了org.jbpm.api.jpdl.DecisionHandler的自定義類,你只需要賦寫String decide(OpenExecution execution) 方法,在該方法最終返回decision活動后的下一個transition的name屬性的值

          詳細的流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="decision" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="61,51,48,48" name="開始">

                <transition g="-47,-17" name="to waite" to="waite"/>

             </start>

             <decision g="188,160,48,48" name="gowhere">

               <handler class="com.jbpm.decision.handler.HandlerDecision"></handler>

                <transition g="-41,-17" name="to 200" to="200">

                </transition>

                <transition g="-41,-17" name="to 500" to="500">

                </transition>

                <transition g="-41,-17" name="to 404" to="404">

                </transition>

             </decision>

             <state g="386,143,92,52" name="200">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="296,261,92,52" name="500">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <state g="197,389,92,52" name="404">

                <transition g="-47,-17" name="to 結束" to="結束"/>

             </state>

             <end g="498,407,48,48" name="結束"/>

             <state g="114,97,92,52" name="waite">

                <transition g="-65,-17" name="to gowhere" to="gowhere"/>

             </state>

          </process>

          請關注紅色標注部分:

          測試代碼:

          Map<String, String> map=new HashMap<String, String>();

                  //towhere為流程定義中表達式的名稱

                  map.put("towhere", "執行到200這個活動");

                  //map.put("towhere", "執行到404這個活動");

                  //map.put("towhere", "執行到500這個活動");

                  ProcessInstance processInstance=executionService.startProcessInstanceByKey("decision",map);

                  System.out.println("流程是否處于waite節點?"+processInstance.isActive("waite"));//true

                  ProcessInstance processInstanceDecision=executionService.signalExecutionById(processInstance.getId());

                  System.out.println("流程是否處于waite節點?"+processInstanceDecision.isActive("waite"));//false

                  System.out.println("流程是否處于gowhere節點?"+processInstanceDecision.isActive("gowhere"));//false

                  System.out.println("流程是否處于200節點?"+processInstanceDecision.isActive("200"));//true

                  System.out.println("流程是否處于404節點?"+processInstanceDecision.isActive("404"));//false

                  System.out.println("流程是否處于500節點?"+processInstanceDecision.isActive("500"));//false

          處理類:

          package com.jbpm.decision.handler;

          import org.jbpm.api.jpdl.DecisionHandler;

          import org.jbpm.api.model.OpenExecution;

          @SuppressWarnings("serial")

          public class HandlerDecision implements DecisionHandler {

              @Override

              public String decide(OpenExecution execution) {

                  String towhere=(String) execution.getVariable("towhere");

                  String result = null;

                  if("執行到200這個活動".equals(towhere)){

                      result="to 200";

                  }else if("執行到404這個活動".equals(towhere)){

                      result="to 404";

                  }else if("執行到500這個活動".equals(towhere)){

                      result="to 500";

                  }

                  return result;

              }

          }

          代碼解釋:

          在測試代碼中同樣創建了一個map對象,然后為該map對象添加了一個以towhere為鍵的值,并在流程實例向下執行的時候傳遞該map對象。

          在HandlerDecision處理類中,通過execution.getVariable("towhere");獲取towhere的value,然后依次判斷,看是否與之前放進去的值匹配,若匹配的話就返回到一個你想使流程向那執行的transition的name屬性的值.至此流程就會沿著這個值的方向向下執行.

          執行結果:

          流程是否處于waite節點?true

          流程是否處于waite節點?false

          流程是否處于gowhere節點?false

          流程是否處于200節點?true

          流程是否處于404節點?false

          流程是否處于500節點?false

          需要說明的是代碼中為map對象設置的鍵值跟流程定義無任何關系,你可以任意設置,只要符合map的使用規律即成,完了在流程實例向下執行的時候順帶傳遞此map對象,最后在自定義的處理類中根據之前的設置的鍵來獲取值,最終返回一個你期望到達的transition即可。

          Task是一個任務活動,主要是在流程實例經過活動時為某一人或組指派任務(流程到達此活動時會暫停下來)

          Task有一個可選的assignee屬性

          第一, assignee用來指示用戶, 負責完成任務的人。分配人是一個任務中的字符串屬性 引用一個用戶。(直接指定一個字符串)

          第二,這個屬性默認會當做表達式來執行。(指定一個表達式,然后在代碼里為該表達式賦值) 如:在這里任務被分配給#{order.owner}。這意味著首先使用order這個名字查找一個對象。 其中一個查找對象的地方是這個任務對應的流程變量。 然后getOwner()方法會用來 獲得用戶id, 引用的用戶負責完成這個任務。

          示例:

          流程定義圖

          第一種情況:(直接指定一個字符串)

          流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="task" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="99,112,48,48" name="start">

                <transition g="-47,-17" name="to task" to="task"/>

             </start>

             <task g="155,221,92,52" name="task" assignee="lisi">

                <transition g="-41,-17" name="to end" to="end"/>

             </task>

             <end g="260,350,48,48" name="end"/>

          </process>

          關注紅色部分

          解釋,在task中直接將任務指派給lisi

          測試代碼(查看lisi的任務列表)

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("task");

                  System.out.println("流程是否處于task節點?"+processInstance.isActive("task"));//true

                  System.out.println("流程實例Id:"+processInstance.getId());

                  List<Task> list=taskService.findPersonalTasks("lisi");

                  for (Task task : list) {

                      System.out.println("任務活動名稱:"+task.getActivityName());

                      System.out.println("流程實例Id:"+task.getExecutionId());

                      System.out.println("任務活動Id:"+task.getId());

                      System.out.println("任務活動創建時間:"+task.getCreateTime());

                      System.out.println("任務活動進度:"+task.getProgress());

                      System.out.println("任務活動分配給:"+task.getAssignee());

                  }

          代碼解釋:

          使用taskService.findPersonalTasks("lisi");即可取得lisi的任務列表

          執行結果:

          流程是否處于task節點?true

          流程實例Id:task.7

          任務活動名稱:task

          流程實例Id:task.7

          任務活動Id:8

          任務活動創建時間:2010-09-29 11:54:34.25

          任務活動進度:null

          任務活動分配給:lisi

          第二種情況:(為task指定一表達式)

          流程定義文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <process name="task" xmlns="http://jbpm.org/4.3/jpdl">

             <start g="99,112,48,48" name="start">

                <transition g="-47,-17" name="to task" to="task"/>

             </start>

             <task g="155,221,92,52" name="task" assignee="${taskAssignee}">

                <transition g="-41,-17" name="to end" to="end"/>

             </task>

             <end g="260,350,48,48" name="end"/>

          </process>

          關注紅色部分

          解釋,在task中使用了表達式${taskAssignee}該值在程序執行時動態分配

          測試代碼(查看任務列表)

          Map<String,String> map=new HashMap<String, String>();

                  map.put("taskAssignee", "lisi");

                  ProcessInstance processInstance=executionService.startProcessInstanceByKey("task",map);

                  System.out.println("流程是否處于task節點?"+processInstance.isActive("task"));//true

                  System.out.println("流程實例Id:"+processInstance.getId());

                  List<Task> list=taskService.findPersonalTasks("lisi");

                  for (Task task : list) {

                      System.out.println("任務活動名稱:"+task.getActivityName());

                      System.out.println("流程實例Id:"+task.getExecutionId());

                      System.out.println("任務活動Id:"+task.getId());

                      System.out.println("任務活動創建時間:"+task.getCreateTime());

                      System.out.println("任務活動進度:"+task.getProgress());

                      System.out.println("任務活動分配給:"+task.getAssignee());

                  }

          代碼解釋:

          在程序一開始創建了一個map對象,并為該map添加一個元素,其鍵為流程定義中的taskAssignee值任意分配,然后傳遞該map,最后查詢任務列表

          執行效果:

          流程是否處于task節點?true

          流程實例Id:task.7

          任務活動名稱:task

          流程實例Id:task.7

          任務活動Id:9

          任務活動創建時間:2010-09-29 11:58:07.359

          任務活動進度:null

          任務活動分配給:lisi

          最后說明一下,在jbpm中表達式$(),#()均可以成功解析

          posted on 2010-09-29 13:52 雪山飛鵠 閱讀(4091) 評論(0)  編輯  收藏 所屬分類: jbpm4
          主站蜘蛛池模板: 黄浦区| 吉林市| 灵寿县| 象州县| 饶平县| 沭阳县| 华池县| 潼南县| 新郑市| 共和县| 武城县| 蒙山县| 阿鲁科尔沁旗| 海原县| 陇南市| 托克逊县| 徐水县| 正镶白旗| 岑溪市| 汝阳县| 阜宁县| 柳林县| 萝北县| 兴安盟| 肥乡县| 兰西县| 大化| 子长县| 虞城县| 兖州市| 固阳县| 自贡市| 尚志市| 绥阳县| 锡林郭勒盟| 太白县| 新营市| 许昌市| 云阳县| 民丰县| 宜兴市|