今日繼續(xù)講解jbpm框架,早上湯老師領(lǐng)著大家把昨天的內(nèi)容復(fù)習(xí)了一下,然后做了總結(jié)。總結(jié)之后十分清晰。
一、昨日回顧
1. 部署流程定義:“deployProcessDefinition”向“jbpm_processdefinition” 表中添加新的流程定義記錄,同時向其子表添加詳細信息。
2. 創(chuàng)建流程實例:“findLatestProcessDefinition”到“jbpm_processdefinition”表中獲取指定名稱的流程定義。“createProcessInstance”創(chuàng)建的流程實例被保存到“jbpm_ processinstance”表中。“pi.getRootToken().signal()”中的Token指向當(dāng)前任務(wù)(游標(biāo)),signal發(fā)出一個信號到達下一個任務(wù)節(jié)點,同時向“jbpm_ taskinstance” 表中添加一個任務(wù)節(jié)點。“pi.getRootToken().signal()”為到達第一個任務(wù)節(jié)點。
3. 獲取任務(wù)實例列表:“getTaskList”根據(jù)指定的actorId到“jbpm_ taskinstance”表中獲取對應(yīng)的任務(wù)列表。
4. 開始任務(wù):“getTaskInstance”到“jbpm_ taskinstance”表中獲取指定的任務(wù)實例。“start”向“jbpm_ taskinstance”表中對應(yīng)的記錄添加任務(wù)起始時間。
5. 結(jié)束任務(wù):“getTaskInstance”到“jbpm_ taskinstance”表中獲取指定的任務(wù)實例。“end”向“jbpm_ taskinstance”表中對應(yīng)的記錄添加任務(wù)結(jié)束時間。“end”內(nèi)部調(diào)用“taskIns.getToken().signal();”指向下一個任務(wù)節(jié)點。
今日新內(nèi)容主要為四點,流程定義文檔、節(jié)點、動作與事件、任務(wù)分配。突然的感覺到事件在JavaEE中被廣泛應(yīng)用,看來事件驅(qū)動還是十分重要的。
二、流程定義文檔(PAR)
1.打包流程文檔時必須使用zip格式。
2.在根目錄中或zip壓縮文件中,包含如下文件:
i. processdefinition.xml(必須,jbpm的流程配置文件。)
ii. processimage.jpg(可選,流程設(shè)計器生成的圖片文件。)
iii. gpd.xml(可選,流程設(shè)計器中圖元的坐標(biāo)等信息。)
iv. classes/(可選,存放用到的java類。)
3.eclipse的jbpm插件可以打包和部署流程,在設(shè)計頁面的標(biāo)簽的旁邊“Deployment”頁面。在“Files and Floders”與“Java Classes and Resources”中,選擇將要打包或部署的文件。“Local Save Settings”打包到…。“Deployment Server Settings”發(fā)布到JBOSS WEB容器,此時必須走動JBOSS WEB容器,采取默認設(shè)置即可。
4.更新的問題(版本)
我們每次部署流程時,JBOSSWEB容器都會為流程設(shè)置一個新的版本,而不會去覆蓋之前部署的應(yīng)用。使用之前的應(yīng)用與對應(yīng)的版本保留,不會造成數(shù)據(jù)出錯。所以每次應(yīng)該重新部署應(yīng)用,也不要刪除以前的應(yīng)用。
如果被刪除或覆蓋,新部署的流程相比以前的流程。多了或少了幾個任務(wù)節(jié)點,那使用之前的數(shù)據(jù)訪問就會出錯。
三、節(jié)點
1.預(yù)定義節(jié)點
1) Start-state:開始狀態(tài)節(jié)點。
2) End-state:結(jié)束狀態(tài)節(jié)點。
3) Task-Node:任務(wù)節(jié)點,非常重要,昨天已經(jīng)學(xué)習(xí)過。
4) Decision:決策分支節(jié)點,此節(jié)點的handler委托類(delegation)必須實現(xiàn)DecisionHandler接口。如:
Start-state | |
需要為Decision的handler頁面的delegation屬性添加一個實現(xiàn)“DecisionHandler”接口的類。 此類返回一個String類型,用于指定decision節(jié)點執(zhí)行哪個分支。 |
實現(xiàn)“DecisionHandler”接口的類:
package cn.itcast.cc.jbpm.node.decision; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.node.Decision; import org.jbpm.graph.node.DecisionHandler; public class DecisionNodeTest extends Decision implements DecisionHandler { private static final long serialVersionUID = @Override public String decide(ExecutionContext arg0) throws Exception { //ExecutionContext節(jié)點的執(zhí)行環(huán)境,通過這個參數(shù)可以獲取所有信息。 return "t2";//執(zhí)行transition名為“t } } |
5) Fork/join:分叉與合并結(jié)點,可以把Fork/join看作是一個大節(jié)點。內(nèi)部包含多條并行的子節(jié)點流程。
Start-state | |
fork | |
兩個分支是并行關(guān)系。直接兩個分支全部執(zhí)行完成,才會到達join。此處自動生成transition名稱,tq和t3。如果沒有,重新連接即可。必須具有transition名稱。 | |
Join,選擇到此處時不全停留,直接到達end-state。 | |
End-state |
6) State:狀態(tài)節(jié)點,當(dāng)流程執(zhí)行到此節(jié)點時會暫停,直到調(diào)用token的signal方法時才會繼續(xù)向下執(zhí)行。(沒有別的用處)
2.自定義節(jié)點
自定義節(jié)點的實現(xiàn)需要使用普通“Node”節(jié)點,與節(jié)點Action動作相配合。以實現(xiàn)預(yù)定義節(jié)點所不能完成的功能。
Node + action示例:
Start-state | |
Node | |
End-state |
為node1的action->details屬性頁面的Handler添加一個實現(xiàn)了“ActionHandler”接口的類(必須選中頁面中的“Configuration Action”),我為在此類中打印一條語語句:
package cn.itcast.cc.jbpm.node.customize; import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext; public class CustomizeAction implements ActionHandler { private static final long serialVersionUID = @Override public void execute(ExecutionContext executionContext) throws Exception { //ExecutionContext節(jié)點的執(zhí)行環(huán)境,通過這個參數(shù)可以獲取所有信息。 System.out.println("*****CustomizeAction*****"); } } |
四、動作與事件
動作我們在第三部分末尾已經(jīng)介紹過,Jbpm的的節(jié)點包含三類事件(共7個事件)。Jbpm7個事件的執(zhí)行順序:
node-leave:離開start-state1節(jié)點,可通過插件配置。 | |
Transition:從start-sate1過渡到task-node1的事件,可通過插件配置。 | |
node-enter:進入task-node1節(jié)點,可通過插件配置。 task-create:創(chuàng)建任務(wù)事件,需要插件/手動配置。 task-assign:分配任務(wù)事件,需要插件/手動配置。 task-start:任務(wù)開始事件,需要插件/手動配置。 task-end:任務(wù)結(jié)束事件,需要插件/手動配置。 | |
… | |
… |
上表中的事件是jbpm流程中比較常用的事件,事件不影響流程的執(zhí)行。
讓我們?yōu)樯厦娴牧鞒烫砑?/span>7個,表中對應(yīng)的事件。事件處理統(tǒng)一使用一個實現(xiàn)了“ActionHandler”接口的類:
package cn.itcast.cc.jbpm.node.event; import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext; public class NodeEventTest implements ActionHandler { private static final long serialVersionUID = @Override public void execute(ExecutionContext executionContext) throws Exception { // 打印事件類型 System.out.println(executionContext.getEvent().getEventType()); } } |
processdefinition.xml文件內(nèi)容為:
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="" name="NodeEvent"> <start-state name="start-state1"> <transition to="task-node1"></transition> <event type="node-leave"> <action class="cn.itcast.cc.jbpm.node.event.NodeEventTest" name="printNodeEventType"></action> </event> </start-state> <task-node name="task-node1"> <task name="下訂單"> <assignment actor-id="客戶"></assignment> <event type="task-create"> <action ref-name="printNodeEventType" /> </event> <event type="task-assign"> <action ref-name="printNodeEventType" /> </event> <event type="task-start"> <action ref-name="printNodeEventType" /> </event> <event type="task-end"> <action ref-name="printNodeEventType" /> </event> </task> <event type="node-enter"> <action ref-name="printNodeEventType"></action> </event> <transition to="end-state1"></transition> </task-node> <end-state name="end-state1"> <event type=""></event> </end-state> </process-definition> |
如果 task-node中包含多個task。將event放在task外部,task-node的內(nèi)部,所有的task將共用同一個事件處理類。如果將event放在task內(nèi)部,task將使用各自內(nèi)部的事件處理類。
將流程發(fā)布到JBOSSWEB容器中(注意將類“NodeEventTest”一同發(fā)布),一步步執(zhí)行查看控制臺的輸出。
五、任務(wù)分配
1.個人任務(wù)(推模型)
個人任務(wù)屬于個人,只有個人能看到,必須由個人完成。個人任務(wù)的分配方式:
1) 手動添加,通過設(shè)計器設(shè)置task的Actor屬性值。
2) Actor:通過設(shè)計器使用表達式將Actor設(shè)置為#{customer},在事件處理函數(shù)中通過“executionContext.getContextInstance().setTransientVariable(name, value)”設(shè)置變量值,動態(tài)更改actor。
3) 為Task的“Assignment->Handler”添加一個實現(xiàn)了AssignmentHandler接口的類,在“assign”方法中調(diào)用“assignable.setActorId(actor);”方法設(shè)置Actor屬性值。
4) 可以在程序的任何位置使用“TaskInstance.setActorId(actor)”設(shè)置Actor的值。
2.組任務(wù)(拉/競爭模型)
組任務(wù)屬于小組,只有小組成員可以查看,但必須僅有一個人來完成。組任務(wù)的分配試:
1) 手動添加,通過設(shè)計器設(shè)置task的PooledActors屬性值,使用“,”分隔。
2) PooledActors:通過設(shè)計器使用表達式將PooledActors屬性設(shè)置為#{actors},在事件處理函數(shù)中通過“executionContext.getContextInstance().setTransientVariable(name, value)”設(shè)置變量值,動態(tài)更改actor。
3) 為Task的“Assignment->Handler”添加一個實現(xiàn)了AssignmentHandler接口的類,在“assign”方法中調(diào)用“assignable. setPooleActors (actors);”方法設(shè)置PooleActors屬性值。
4) 可以在程序的任何位置使用“taskInstance.setPooledActors(actors)”,設(shè)置PooledActors的值。
3.查詢
1) 個人任務(wù):jbpmContext.getTaskMgmtSession().findTaskInstances (actorId)。
2) 組任務(wù):jbpmContext.getTaskMgmtSession().findPooledTaskInstances(actorId)。
actorId可以屏蔽pooledActors
4.Swimlane(泳道)
湯兄弟今天只是簡單介紹了一下泳道,這個功能并不常用。
泳道圖:
OK,今天的內(nèi)容到此結(jié)束。明天就開始我們的OA系統(tǒng)了,主要使用struts+hibernate+jbpm開發(fā)!
哈哈,加油!