自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

jBPM實現(xiàn)高級交互模式詳解

開發(fā) 后端
jBpm是一個非常好用的業(yè)務(wù)流程管理,其涉足領(lǐng)域包括業(yè)務(wù)流程管理、工作流、服務(wù)協(xié)作等。在這片文章中會針對jBpm高級交互模式的實現(xiàn)操作技巧進行一個詳細介紹,幫助大家理解。

JBPM是目前應(yīng)用廣泛的Java工作流管理系統(tǒng),在51CTO之前報道的J2EE工作流管理系統(tǒng)JBPM詳解中,我們曾詳細介紹過JBPM的工作原理和工作流應(yīng)用方案。今天通過對JBPM中的四眼原則、任命和上報的實現(xiàn)來詳細講解如何使用JBPM實現(xiàn)高級交互模式。

#t#

許多通用業(yè)務(wù)流程都包含人類參與者。人類活動,從簡單場景(如人工批準)到復雜場景(涉及復雜的數(shù)據(jù)輸入),在流程實現(xiàn)中引入了新的方面,如人類交互模式。人類交互模式的一個典型集合包括:

1、四眼原則(The 4-eyes principle),通常又被稱為“職責分離”,它是決策由多人彼此獨立作出時的一個常見場景。在很多情況下,很容易就能得到另一個觀點/簽名。

2、任命(Nomination)是指上級根據(jù)團隊成員的任務(wù)安排、工作負荷或經(jīng)驗人工地將任務(wù)分配給他的情形。

3、任務(wù)通常被建模來表達一種預期:它們將在確定時間段內(nèi)完成。如果任務(wù)沒有按預期地進展,就需要一種上報(escalation)機制。兩種典型的上報實現(xiàn)是:重新分配任務(wù),并常常附帶一個上報已經(jīng)發(fā)生的通知;或任務(wù)未按時完成的通知(通常發(fā)給經(jīng)理)。

4、鏈狀執(zhí)行(Chained execution)是一個流程(片斷),其中的一系列步驟是由同一個人來完成。

在本文中,我將討論如何實現(xiàn)JBPM高級交互模式。

JBPM中的任務(wù)管理

JBPM的一個核心功能2是為人類管理任務(wù)和任務(wù)列表。JBPM允許將任務(wù)和任務(wù)節(jié)點作為整個流程設(shè)計的一部分使用。

任務(wù)一般在JBPM中定義成任務(wù)節(jié)點。單個任務(wù)節(jié)點可以包含一個或多個任務(wù)。包含任務(wù)節(jié)點的JBPM流程的一個公共行為就是等待任務(wù)節(jié)點中的全部任務(wù)完成,然后繼續(xù)執(zhí)行。某個任務(wù)可被分配3 給個人、用戶組或泳道:

假如任務(wù)被分配給某個特定用戶,那么就只有這個使用者可以執(zhí)行它。

假如任務(wù)被分配給某個用戶組,那么這個組內(nèi)的任何參與者都能執(zhí)行這個任務(wù)。JBPM使用的是參與者池(pooled actors)符號(它可以包含組名、組名列表和參與者個人列表等),而不是組ID。如果用戶開始執(zhí)行在他們組任務(wù)列表中的任務(wù),最終可能會引起沖突4——可能有多人開始執(zhí)行相同的任務(wù)。為了避免這種情況,在開始執(zhí)行任務(wù)之前,用戶應(yīng)該將任務(wù)從組任務(wù)列表移動到他們自己的任務(wù)列表中。

泳道代表一個流程角色,它通常被分配給一個用戶組。它是一種指定流程中的多個任務(wù)要由同一參與者完成的機制5。因此,在第一個任務(wù)被分配給某個泳道之后,流程就會記住所有在相同泳道內(nèi)的后續(xù)任務(wù)都將由同一參與者完成。

JBPM提供了兩種定義任務(wù)分配的基本方法:作為流程定義的一部分或通過編程實現(xiàn)。如果是作為流程定義的一部分,分配可以通過指定具體用戶、用戶組或泳道完成。此外,可以使用表達式根據(jù)流程變量動態(tài)確定某個具體用戶。完整的編程實現(xiàn)是基于分配處理器(assignment handler)的6,它允許任務(wù)根據(jù)任意的計算規(guī)則去查找用戶ID。那么如何才能很好的實現(xiàn)JBPM高級交互模式這一功能呢,讓我們繼續(xù)往下看。

流程定義描述流程實例的方式類似任務(wù)描述任務(wù)實例的方式。當流程執(zhí)行時,一個流程實例——流程的運行時表示——就會被創(chuàng)建。類似,一個任務(wù)實例——任務(wù)的運行時表示——就會被創(chuàng)建。根據(jù)任務(wù)定義,任務(wù)實例被分配給一個參與者/參與者組。

任務(wù)實例的一個作用就是支持用戶交互——把數(shù)據(jù)顯示給用戶并從用戶那里收集數(shù)據(jù)。一個JBPM任務(wù)實例擁有訪問流程(令牌)變量7的全部權(quán)限,而且還可以有自己的變量。任務(wù)能夠擁有自己的變量對于以下場景非常有用:

在任務(wù)實例中創(chuàng)建流程變量的副本,這樣對任務(wù)實例變量的即時更新只有在該任務(wù)完成且這些副本被提交給流程變量時才會影響流程變量。

創(chuàng)建更好支持用戶活動的“派生(計算)”變量。

任務(wù)自己的變量在JBPM中是通過任務(wù)控制器處理器(task controller handler)支持的,它可以在任務(wù)實例創(chuàng)建時生成任務(wù)實例數(shù)據(jù)(從流程數(shù)據(jù)),并在任務(wù)實例完成時將任務(wù)實例數(shù)據(jù)提交給流程變量。

#p#

擴展Task類

JBPM高級交互模式的實現(xiàn)操作中任務(wù)的定義被包含在org.JBPM.taskmgmt.def.Task類中。為了支持四眼原則,我們需要給類增加以下的字段/方法(清單1):

  1. protected int numSignatures = 1;  
  2. public int getNumSignatures(){  
  3. return numSignatures;  
  4. }  
  5. public void setNumSignatures
    (int numSignatures){  
  6. this.numSignatures = 
    numSignatures;  

清單1 給Task類增加字段和方法

這個新的參數(shù)允許指定任務(wù)完成所需的JBPM高級交互模式任務(wù)處理人數(shù)量。缺省值為1,這意味著,只有1個用戶應(yīng)該/可以處理這個任務(wù)。

JBPM使用Hibernate來向數(shù)據(jù)庫保存和讀取數(shù)據(jù)。為了讓我們新加的變量持久化,我們需要更新Task類的Hibernate配置文件(Task.hbm.xml),它在org.JBPM.taskmgmt.def文件夾中,增加代碼如下(清單2)

  1. <  property name="numSignatures" 
    column="NUMSIGNATURES_" /> 

清單2 在Task映射文件中指定新增域

為了讓我們新加的屬性能被流程定義和數(shù)據(jù)庫正確讀取,我們需要修改org.JBPM.jpdl.xml.JpdlXmlReader類以正確地讀取我們的新屬性(清單3)

  1. String numSignatureText = 
    taskElement.attributeValue
    ("numSignatures");  
  2. if (numSignatureText != null) {  
  3. try{  
  4. task.setNumSignatures
    (Integer.parseInt(num
    SignatureText));  
  5. }  
  6. catch(Exception e){}  

清單3 讀取numSignature屬性

最后,因為JpdlXmlReader根據(jù)模式來驗證XML,因此我們需要在jpdl-3.2.xsd中增加一個屬性定義(清單4):

  1. <  xs:element name="task"> 
  2. ………………….  
  3. <  xs:attribute name=
    "numSignatures" type=
    "xs:string" /> 

清單4 在jpdl-3.2.xsd中增加numSignatures屬性

當完成這些工作,JBPM高級交互模式的任務(wù)定義就被擴展可以使用numSignatures屬性(清單5):

  1. <  task name="task2" 
    numSignatures = "2">   
  2. <  assignment pooled-actors
    ="Peter, John"> 
  3. <  /assignment>   
  4. <  /task> 

清單5 給任務(wù)定義增加numSignatures屬性

#p#

擴展TaskInstance類

在JBPM高級交互模式實現(xiàn)操作到此處時,擴展完任務(wù)類后,我們還需要創(chuàng)建一個自定義的任務(wù)實例類來跟蹤分配給該任務(wù)實例的參與者,并確保所有被分配的參與者完成類執(zhí)行(清單6)。

  1. package com.navteq.JBPM.extensions;  
  2. import java.util.Date;  
  3. import java.util.LinkedList;  
  4. import java.util.List;  
  5. import org.JBPM.JBPMException;  
  6. import org.JBPM.taskmgmt.exe.TaskInstance;  
  7. public class AssignableTaskInstance 
    extends TaskInstance {  
  8. private static final long 
    serialVersionUID = 1L;  
  9. private List< Assignee> assignees = 
    new LinkedList< Assignee>();  
  10. private String getAssigneeIDs(){  
  11. StringBuffer sb = new StringBuffer();  
  12. boolean first = true;  
  13. for(Assignee a : assignees){  
  14. if(!first)  
  15. sb.append(" ");  
  16. else   
  17. first = false;  
  18. sb.append(a.getUserID());  
  19. }  
  20. return sb.toString();  
  21. }  
  22. public List< Assignee> getAssignees() {  
  23. return assignees;  
  24. }  
  25. public void reserve(String userID) 
    throws 
    JBPMException{  
  26. if(task == null)  
  27. throw new JBPMException("can't 
    reserve instance with no task");  
  28. // Duplicate assignment is ok  
  29. for(Assignee a : assignees){  
  30. if(userID.equals(a.getUserID()))  
  31. return;  
  32. }  
  33. // Can we add one more guy?  
  34. if(task.getNumSignatures() > 
    assignees.size()){  
  35. assignees.add(new Assignee(userID));  
  36. return;  
  37. }  
  38. throw new JBPMException("task 
    is already reserved by " +  
  39. getAssigneeIDs());  
  40. }  
  41. public void unreserve(String userID){  
  42. for(Assignee a : assignees){  
  43. if(userID.equals(a.getUserID())){  
  44. assignees.remove(a);  
  45. return;  
  46. }  
  47. }  
  48. }  
  49. private void completeTask(Assignee 
    assignee, String transition){  
  50. assignee.setEndDate(new Date());  
  51. // Calculate completed assignments  
  52. int completed = 0;  
  53. for(Assignee a : assignees){  
  54. if(a.getEndDate() != null)  
  55. completed ++;  
  56. }  
  57. if(completed <  task.getNumSignatures())  
  58. return;  
  59. if(transition == null)  
  60. end();  
  61. else   
  62. end(transition);  
  63. }  
  64. public void complete(String userID, 
    String transition) throws 
    JBPMException{  
  65. if(task == null)  
  66. throw new JBPMException("can't 
    complete instance with no task");  
  67. // make sure it was reserved  
  68. for(Assignee a : assignees){  
  69. if(userID.equals(a.getUserID())){  
  70. completeTask(a, transition);  
  71. return;  
  72. }  
  73. }  
  74. throw new JBPMException("task 
    was not reserved by " + userID);  
  75. }  
  76. public boolean isCompleted(){  
  77. return (end != null);  
  78. }  

清單6 擴展TaskInstance類

這個JBPM高級交互模式的操作實現(xiàn)擴展了JBPM提供的TaskInstance類,并跟蹤完成該實例所需的參與者個數(shù)。它引入了幾個新方法,允許參與者預留(reserve)/退還(unreserve)任務(wù)實例,以及讓指定參與者完成任務(wù)執(zhí)行。

#p#

JBPM高級交互模式的實現(xiàn)操作中,清單6的實現(xiàn)依賴一個支持類Assignee(清單7)

  1. package com.navteq.JBPM.extensions;  
  2. import java.io.Serializable;  
  3. import java.text.DateFormat;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.Date;  
  6. public class Assignee implements 
    Serializable{  
  7. private static final long 
    serialVersionUID = 1L;  
  8. private static final DateFormat 
    dateFormat = new   
  9. SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  
  10. long id = 0;  
  11. protected String startDate = null;  
  12. protected String userID = null;  
  13. protected String endDate = null;  
  14. public Assignee(){}  
  15. public Assignee(String uID){  
  16. userID = uID;  
  17. startDate = dateFormat.format(new Date());  
  18. }  
  19. //////Setters and Getters //////  
  20. public long getId() {  
  21. return id;  
  22. }  
  23. public void setId(long id) {  
  24. this.id = id;  
  25. }  
  26. public String getStartDate() {  
  27. return startDate;  
  28. }  
  29. public void setStartDate(String startDate) {  
  30. this.startDate = startDate;  
  31. }  
  32. public String getUserID() {  
  33. return userID;  
  34. }  
  35. public void setUserID(String id) {  
  36. userID = id;  
  37. }  
  38. public String getEndDate() {  
  39. return endDate;  
  40. }  
  41. public void setEndDate(String endDate) {  
  42. this.endDate = endDate;  
  43. }  
  44. public void setEndDate(Date endDate) {  
  45. this.endDate = dateFormat.format(endDate);  
  46. }  
  47. public void setEndDate() {  
  48. this.endDate = dateFormat.format(new Date());  
  49. }  
  50. public String toString(){  
  51. StringBuffer bf = new StringBuffer();  
  52. bf.append(" Assigned to ");  
  53. bf.append(userID);  
  54. bf.append(" at ");  
  55. bf.append(startDate);  
  56. bf.append(" completed at ");  
  57. bf.append(endDate);  
  58. return bf.toString();  
  59. }  

清單7 Assignee類

#p#

JBPM高級交互模式自定義的TaskInstance類和Assignee類都必須保存到數(shù)據(jù)庫中。這意味著需要給這兩個類實現(xiàn)Hibernate映射14 (清單8,9):

  1. <  ?xml version="1.0"?>   
  2. <  !DOCTYPE hibernate-mapping PUBLIC "-
    //Hibernate/Hibernate Mapping DTD 3.0
    //EN" "http://hibernate.sourceforge.net
    /hibernate-mapping-3.0.dtd"
    >   
  3. <  hibernate-mapping auto-import="false" 
    default-access="field">   
  4. <  subclass namename="com.navteq.JBPM.
    extensions.AssignableTaskInstance"
     
    extends="org.JBPM.taskmgmt.exe.
    TaskInstance"
     discriminator-value="A">   
  5. <  list name="assignees" cascade="all" >   
  6. <  key column="TASKINSTANCE_" />   
  7. <  index column="TASKINSTANCEINDEX_"/>   
  8. <  one-to-many class="com.navteq.
    JBPM.extensions.Assignee"
     />   
  9. <  /list>   
  10. <  /subclass>   
  11. <  /hibernate-mapping> 

清單8 自定義任務(wù)實例的Hibernate映射文件

  1. <  ?xml version="1.0"?>   
  2. <  !DOCTYPE hibernate-mapping PUBLIC "-
    //Hibernate/Hibernate Mapping DTD 3.0
    //EN" "http://hibernate.sourceforge.net
    /hibernate-mapping-3.0.dtd"
    >   
  3. <  hibernate-mapping auto-import=
    "false" default-access="field">   
  4. <  class name="com.navteq.JBPM.
    extensions.Assignee"
     table=
    "JBPM_ASSIGNEE">   
  5. <  cache usage="nonstrict-read-write"/>   
  6. <  id name="id" column="ID_"> 
  7. <  generator class="native" /> 
  8. <  /id> <  !-- Content -->   
  9. <  property name="startDate" 
    column="STARTDATE_" />   
  10. <  property name="userID" 
    column="USERID_" />   
  11. <  property name="endDate" 
    column="ENDDATE_" />   
  12. <  /class>   
  13. <  /hibernate-mapping> 

清單9 Assignee類的Hibernate映射文件

要讓JBPM高級交互模式的實現(xiàn)操作能夠使用我們的自定義任務(wù)實例實現(xiàn),我們還需要提供一個自定義的任務(wù)實例工廠(清單10)。

  1. package com.navteq.JBPM.extensions;  
  2. import org.JBPM.graph.exe.ExecutionContext;  
  3. import org.JBPM.taskmgmt.TaskInstanceFactory;  
  4. import org.JBPM.taskmgmt.exe.TaskInstance;  
  5. public class AssignableTaskInstanceFactory 
    implements TaskInstanceFactory {  
  6. private static final long serialVersionUID = 1L;  
  7. @Override  
  8. public TaskInstance createTaskInstance
    (ExecutionContext executionContext) {  
  9. return new AssignableTaskInstance();  
  10. }  

清單10 自定義的任務(wù)實例工廠

最后,為了讓JBPM運行時使用正確的任務(wù)實例工廠(清單10),還必須創(chuàng)建一個新的JBPM配置(清單11)。

  1. <  JBPM-configuration>   
  2. <  bean name="JBPM.task.instance.
    factory"
     class="com.navteq.JBPM.
    extensions.AssignableTask
    InstanceFactory"
     singleton="true" />   
  3. <  /JBPM-configuration> 

清單11 JBPM配置

完成所有這些變更之后(清單1-11),一個典型的任務(wù)處理顯示如下:

  1. List<  String> actorIds = 
    new LinkedList
    <  String>();  
  2. actorIds.add("Peter");  
  3. List<  TaskInstance> cTasks = 
    JBPMContext.getGroupTaskList(actorIds)  
  4. TaskInstance cTask = cTasks.get(0);  
  5. AssignableTaskInstance aTask = 
    (AssignableTaskInstance)cTask;  
  6. try{  
  7. aTask.reserve("Peter");  
  8. // Save  
  9. JBPMContext.close();  
  10. }  
  11. catch(Exception e){  
  12. System.out.println("Task " + 
    cTask.getName() + " is already reserved");  
  13. e.printStackTrace();  

清單12 處理可分配任務(wù)實例

這里,在得到某個用戶的任務(wù)實例并將其轉(zhuǎn)變成可分配任務(wù)實例之后,我們將試著預留它15。一旦預留成功,我們將關(guān)閉JBPM高級交互模式運行時以提交事務(wù)。

#p#

實現(xiàn)任命

JBoss JBPM可以非常輕易的實現(xiàn)手動將任務(wù)分配給特定用戶。根據(jù)JBPM提供的簡單API,可以完成將任務(wù)實例從一個任務(wù)列表移動到另一個任務(wù)列表,因此給某個用戶分配任務(wù)相當直接(清單13)

  1. List< String> actorIds = 
    new LinkedList< String>();  
  2. actorIds.add("admins");  
  3. String actorID = "admin";  
  4. List< TaskInstance> cTasks = 
    JBPMContext.getGroupTaskList(actorIds);  
  5. TaskInstance cTask = cTasks.get(0);  
  6. cTask.setPooledActors((Set)null);  
  7. cTask.setActorId(actorID); 

 

清單13 將任務(wù)重新分配給指定用戶

在JBPM高級交互模式的操作中,提供了2類不同的API來設(shè)置參與者池:一類接收字符串id數(shù)組,另一類則接收id集合。如果要清空一個池,就要使用那個接收集合的API(傳入一個null集合)。

實現(xiàn)上報

前面已經(jīng)說過,上報一般被實現(xiàn)為任務(wù)的重新分配,并常常附帶一個上報已發(fā)生的通知;或是實現(xiàn)成一個任務(wù)未及時完成的通知。

實現(xiàn)為重新分配的上報

盡管JBPM不直接支持上報,但它提供了2個基本的機制:超時和重新分配(參見上節(jié))。粗一看,實現(xiàn)上報只需將這二者結(jié)合即可,但是仔細一想還是存在一些困難:

JBPM實現(xiàn)中的關(guān)系并不總是雙向的。如,從一個任務(wù)節(jié)點我們可以找到所有這個節(jié)點定義的任務(wù),但是從一個任務(wù),并沒有API可以完成找到包含它的任務(wù)節(jié)點的工作16;由某個任務(wù)實例,你可以得到一個任務(wù),但是沒有由某個任務(wù)得到所有實例的API,諸如此類。

超時不是發(fā)生在任務(wù)自身,而是發(fā)生在任務(wù)節(jié)點上。由于某個節(jié)點可以關(guān)聯(lián)多個任務(wù),并且JBPM關(guān)系實現(xiàn)并不是雙向的(見上),因此要跟蹤當前任務(wù)實例就需要其他的支持手段。
以重新分配實現(xiàn)的上報的整個實現(xiàn)17涉及3個處理器:

負責給任務(wù)分配參與者的分配處理器。這個處理器跟蹤它是一個首次任務(wù)調(diào)用還是一個上報任務(wù)調(diào)用。清單14給出了一個分配處理器的例子。

  1. package com.sample.action;  
  2. import org.JBPM.graph.def.Node;  
  3. import org.JBPM.graph.exe.
    ExecutionContext;  
  4. import org.JBPM.taskmgmt.def.
    AssignmentHandler;  
  5. import org.JBPM.taskmgmt.exe.
    Assignable;  
  6. public class EscalationAssi
    gnmentHandler implements 
    AssignmentHandler {  
  7. private static final long 
    serialVersionUID = 1L;  
  8. @Override  
  9. public void assign(Assignable assignable, 
    ExecutionContext context)  
  10. throws Exception {  
  11. Node task = context.getToken().getNode();  
  12. if(task != null){  
  13. String tName = task.getName();  
  14. String vName = tName + "escLevel";  
  15. Long escLevel = (Long)context.
    getVariable(vName);  
  16. if(escLevel == null){  
  17. // First time through  
  18. assignable.setActorId("admin");  
  19. }  
  20. else{  
  21. // Escalate  
  22. assignable.setActorId("bob");  
  23. }  
  24. }  
  25. }  

清單14 分配處理器示例

在JBPM高級交互模式的實現(xiàn)操作中我們嘗試得到一個包含了給定任務(wù)上報次數(shù)的流程變量。如果變量未定義,則就分配“admin”為任務(wù)擁有者,否則任務(wù)就被分配給“bob”。在這個處理器中可以使用任何其他的分配策略。

任務(wù)實例創(chuàng)建動作處理器(清單15),它保存流程實例上下文的任務(wù)實例id

  1. package com.sample.action;  
  2. import org.JBPM.graph.def.ActionHandler;  
  3. import org.JBPM.graph.def.Node;  
  4. import org.JBPM.graph.exe.ExecutionContext;  
  5. import org.JBPM.taskmgmt.exe.TaskInstance;  
  6. public class TaskCreationActionHandler 
    implements ActionHandler {  
  7. private static final long 
    serialVersionUID = 1L;  
  8. @Override  
  9. public void execute(ExecutionContext 
    context) throws Exception {  
  10. Node task = context.getToken().getNode();  
  11. TaskInstance current = 
    context.getTaskInstance();  
  12. if((task == null) || (current == null))  
  13. return;  
  14. String tName = task.getName();  
  15. String iName = tName + "instance";  
  16. context.setVariable(iName, 
    new Long(current.getId()));  
  17. }  

清單15 任務(wù)實例創(chuàng)建處理器

JBPM高級交互模式中任務(wù)節(jié)點計時器觸發(fā)調(diào)用的超時處理器(清單16)。

  1. package com.sample.action;  
  2. import org.JBPM.graph.def.ActionHandler;  
  3. import org.JBPM.graph.def.GraphElement;  
  4. import org.JBPM.graph.exe.ExecutionContext;  
  5. import org.JBPM.taskmgmt.exe.TaskInstance;  
  6. public class EscalationActionHandler 
    implements ActionHandler {  
  7. private static final long 
    serialVersionUID = 1L;  
  8. private String escalation;  
  9. @Override  
  10. public void execute(ExecutionContext 
    context) throws Exception {  
  11. GraphElement task = context.getTimer().
    getGraphElement();  
  12. if(task == null)  
  13. return;  
  14. String tName = task.getName();  
  15. String vName = tName + "escLevel";  
  16. long escLevel = (long)context.
    getVariable(vName);  
  17. if(escLevel == null)  
  18. escLevel = new long(1);  
  19. else  
  20. escLevel += 1;  
  21. context.setVariable(vName, escLevel);  
  22. String iName = tName + "instance";  
  23. long taskInstanceId = (long)
    context.getVariable(iName);  
  24. TaskInstance current =   
  25. context.getJBPMContext().
    getTaskInstance(taskInstanceId);  
  26. if(current != null){  
  27. current.end(escalation);  
  28. }  
  29. }  

清單16 超時處理器

這個處理器首先記錄上報計數(shù)器,接著完成此節(jié)點關(guān)聯(lián)的任務(wù)實例。任務(wù)實例的完成伴隨有一個變遷(一般是回到任務(wù)節(jié)點)。

使用以上描述的處理器實現(xiàn)JBPM高級交互模式的上報的簡單流程例子顯示在清單17中。

  1. < ?xml version="1.0" encoding="UTF-8"?>   
  2. < process-definition xmlns="urn:JBPM.
    org:jpdl-3.2"
     name="escalationHumanTaskTest">   
  3. < start-state name="start">   
  4. < transition to="customTask"> 
  5. < /transition>   
  6. < /start-state>   
  7. < task-node name="customTask">   
  8. < task name="task2">   
  9. < assignment class="com.sample.action.
    EscalationAssignmentHandler"
    > 
  10. < /assignment>   
  11. < /task>   
  12. < event type="task-create">   
  13. < action name="Instance Tracking" 
    class="com.sample.action.
    TaskCreationActionHandler"
    > 
  14. < /action>   
  15. < /event>   
  16. < timer duedate="10 second" 
    name="Escalation timeout">   
  17. < action class="com.sample.action.
    EscalationActionHandler"
    > < escalation>   
  18. escalation   
  19. < /escalation>   
  20. < /action>   
  21. < /timer>   
  22. < transition to="end" name="to end"> 
  23. < /transition>   
  24. < transition to="customTask" 
    name="escalation"> 
  25. < /transition>   
  26. < /task-node>   
  27. < end-state name="end"> 
  28. < /end-state>   
  29. < /process-definition> 

清單17 簡單流程的上報

實現(xiàn)成通知的上報

JBPM為郵件傳遞提供了強大支持18,這使得實現(xiàn)成通知的上報變得極其簡單。郵件傳遞可由給節(jié)點附加定時器,然后觸發(fā),它使用已經(jīng)寫好的郵件動作來完成通知傳遞。

實現(xiàn)鏈狀執(zhí)行

鏈狀執(zhí)行直接由JBPM泳道支持,并不需要額外的開發(fā)。

總結(jié)

不管我們在自動化方面投入多少努力,面對復雜的業(yè)務(wù)流程,總免不了要有人工介入的可能。在這篇JBPM高級交互模式的操作介紹的文章中,我給出了一系列已建立的高級人工交互模式,并展示了用JBPM完成它是多么輕而易舉。

責任編輯:曹凱 來源: infoq.com
相關(guān)推薦

2009-06-26 13:51:49

jBPM4高級圖形執(zhí)行

2009-08-25 18:04:30

C#實現(xiàn)Singlet

2009-06-26 09:32:35

jBPM4基本活動

2009-06-26 09:15:31

jBPM4基本活動

2010-06-04 15:59:45

Hadoop完全分布模

2011-06-28 15:18:45

Qt 單例模式

2021-09-12 07:30:10

配置

2010-10-19 16:32:46

MySQL

2009-06-24 16:23:29

jBPM 4.0配置

2010-05-12 16:13:04

2010-02-06 13:42:36

C++單件模式

2021-06-29 08:54:23

設(shè)計模式代理模式遠程代理

2009-08-07 14:10:13

C# WebserviDelphi

2019-08-30 07:24:16

2010-06-13 09:15:16

WinForm窗體

2011-06-28 15:01:01

Qt PIMPL

2021-07-07 10:31:19

對象池模式解釋器模式設(shè)計模式

2009-06-11 13:53:35

jBPM用戶指南

2009-06-25 17:13:51

jBPM與Spring

2009-06-24 14:57:03

jBPM4架構(gòu)
點贊
收藏

51CTO技術(shù)棧公眾號