摘 要: 介紹了國內(nèi)目前的工作流領(lǐng)域特點,,尤其對臨時動態(tài)性需求(會簽,、撤銷、任意回退等)的各種場景進行了分析,,提出了基于jBPM4的解決思路及一種動態(tài)路由的方法,,以解決臨時回退的問題。
關(guān)鍵詞: jBPM,;臨時動態(tài)性需求,;動態(tài)路由
工作流管理技術(shù)[1-2]作為一種過程建模和過程管理的核心技術(shù),是新興于20世紀90年代的一種信息化技術(shù),。隨著近些年國內(nèi)企業(yè),、政府信息化的建設(shè),工作流技術(shù)被越來越廣泛地應用于業(yè)務流程管理(BPM)領(lǐng)域,。jBPM是一種輕量級的J2EE開源框架,,具有良好的可擴展性。其最新版本較jBPM3.2版本,,在核心引擎等方面都有較大改動,,本文總結(jié)了新版本的特點。結(jié)合國內(nèi)工作流領(lǐng)域的應用特點,,本文特別針對臨時動態(tài)性需求,,分析了各種場景的情況,,給出了應用jBPM4的解決思路,為解決臨時回退的問題,,提出了一種動態(tài)路由的方法,,該方法亦可以用于解決各種臨時動態(tài)性需求的場景。
1 jBPM4特點
jBPM是JBoss眾多開源項目中的一個工作流開源項目,,也是目前應用最廣泛的工作流項目,。在2009年7月10日,JBoss jBPM團隊發(fā)布了jBPM4的正式版本,。jBPM4完全基于流程虛擬機(PVM)的機制,,對核心引擎進行了重新設(shè)計,而PVM的引入也使jBPM4可以支持多流程語言[3],。jBPM4特點如下:
(1)在流程定義的對象上,,節(jié)點類型劃分更清晰。
(2)基于觀察者模式的事件監(jiān)聽(Event-Listener)機制,。在jBPM4中活動節(jié)點對象(ActivityImpl),、轉(zhuǎn)移對象(TransitionImpl)、流程定義對象(ProcessDefinitionImpl),,全都繼承了ObservableElementImpl對象,,因此,,組成流程定義的3個主要元素都可作為觀察者模式中的被觀察者來觀察,,而這些對象本身就直接支持注冊各種事件(Event),然后由監(jiān)聽器(Listener)來監(jiān)聽這些Event,。
(3)基于ExecutionImpl,、Command模式和AtomicOperation實現(xiàn)的內(nèi)核引擎在jBPM4中用ExcutionImpl代替jBPM3中Token機制。流程的流轉(zhuǎn)依賴于ExcutionImpl調(diào)用各個AtomicOperation原子操作,,如ExecuteActivity,、MoveToParentActivity、TransitionTake,、TransitionStartActivity,、ExecuteEventListener、TransitionEndActivity進行推進,,而ExecutionImpl在各個實例對象之間進行轉(zhuǎn)移,。
(4)加入了歷史庫,但還不完善,。
2 國內(nèi)工作流領(lǐng)域的特點
目前國內(nèi)在工作流領(lǐng)域[4]主要的應用是人工工作流,,也就是以人工任務密集型的工作流為主。隨著國內(nèi)企業(yè)和公共組織的信息化發(fā)展越來越快,,IT系統(tǒng)的積累和建設(shè)經(jīng)驗也越來越豐富,,以自動任務密集型為主的應用將會逐漸增多。人工任務密集型工作流的應用主要集中在以下領(lǐng)域:電子政務,行政審批,,企業(yè)協(xié)同辦公,,電信、電力的工單,,企業(yè)采購,、合同、銷售等,。
從功能需求上,,這些人工任務密集型流程的典型特點主要有:(1)用戶友好的流程定義工具。(2)表單能夠自定義,。(3)靈活的臨時動態(tài)性需求,,例如:任意回退、會簽,、撤銷等,。這些需求,存在很強的人為性因素,。
國內(nèi)專注于工作流產(chǎn)品方面的公司起步較國外晚,,其產(chǎn)品大多只專注于某個行業(yè)的具體需求,如:有生博大的工作流產(chǎn)品主要定位于“電子政務系統(tǒng)中的審批流”,;西安協(xié)同的工作流產(chǎn)品偏重于“電信行業(yè)”,;信雅達的工作流產(chǎn)品偏重于“金融行業(yè)”;上海東蘭的工作流產(chǎn)品則偏重于“協(xié)同領(lǐng)域”等等,。
3 各種臨時動態(tài)性需求情況的解決思路
jBPM4是由國外開源小組領(lǐng)導的項目,,流程定義工具和表單設(shè)計并不是其項目的特點,但其在流程處理方面的思想有其特色,,特別是流程核心引擎的架構(gòu)很值得學習研究,。筆者在學習研究的過程中,對國內(nèi)靈活的各種臨時動態(tài)性需求的場景進行了模擬分析,,提出了如何應用jBPM4來解決問題的思路,。
3.1 會簽
會簽在政府或企業(yè)都是必不可少的功能,尤其是審批流中,。會簽可以分為單步會簽(只有1個審批環(huán)節(jié))及多步會簽(每1個子審批流有多個審批環(huán)節(jié)),。單步會簽:在流程的某個環(huán)節(jié)需要由多個辦理人(多個不同部門的領(lǐng)導)共同辦理或者簽署意見,這是企業(yè)或政府的內(nèi)部最為常見的情況,。多步會簽(也稱為并聯(lián)審批):其實質(zhì)就是一個單步的審批環(huán)節(jié)變?yōu)榱嗽诓块T內(nèi)部一個比較復雜的審批流程,,這個審批流程有多個審批環(huán)節(jié)。
多步會簽的情況較為復雜,,本文只提供應用jBPM4解決單步會簽的思路:即對TaskService進行擴展開發(fā),,實現(xiàn)動態(tài)任務實例的創(chuàng)建,,參照TaskActivity類中的方法進行擴展,擴展后再調(diào)用addTaskParticipatingUser( )或addTaskParticipatingGroup( )方法實現(xiàn)動態(tài)增加任務辦理人,,此時即實現(xiàn)了單步會簽功能。
3.2 撤銷
撤銷是指任務在發(fā)送給下一個辦理人之后,,發(fā)現(xiàn)任務發(fā)送錯誤,,此時在下一個辦理人還沒有辦理之前,可以撤回當前任務,,而重新選擇其他人進行辦理,。串行流程如圖1所示。
節(jié)點2的處理人(假設(shè)是王二)辦理完畢之后,,將任務提交,,此時任務到達了節(jié)點3(假設(shè)李三辦理),這時李三就會收到一個待辦任務,,在李三還沒有辦理之前,,王二突然發(fā)現(xiàn),有1個業(yè)務數(shù)據(jù)填寫錯誤,,或者粘貼的附件錯誤,,這時王二需要將發(fā)送給李三的任務撤銷,重新更正數(shù)據(jù)后或修改粘貼的附件后再發(fā)送給李三審批,。此外,,假設(shè)節(jié)點3的辦理人有2個人(李三和趙五),那么王二需要在運行期間根據(jù)業(yè)務特性手動地選擇任務是提交給李三還是趙五,,但由于王二的誤操作,,把本來應該發(fā)給趙五的辦理任務錯發(fā)送給了李三,,此時,,在李三辦理之前,,王二也可以將發(fā)送給李三的任務撤銷,,然后重新發(fā)送給趙五。
對于上述模擬的撤銷,,jBPM4解決思路如下:
(1)刪除需要撤銷的任務實例及其與此任務實例相關(guān)的所有工作流實例,。在文件TaskServiceImpl.java中,,jBPM4提供了級聯(lián)刪除任務實例的相關(guān)方法:
public void deleteTaskCascade(String taskId) {
commandService.execute(new DeleteTaskCmd(taskId,true)),;
}
(2)修改當前任務實例的狀態(tài),。即將張三的已經(jīng)辦理完畢的節(jié)點2對應的TaskInstance的狀態(tài)更改為待辦狀態(tài):(Task.STATE_OPEN)
task.setState(ask.STATE_OPEN);
taskService.saveTask(task),;
3.3 任意回退
回退作為審批流最常見的需求,,每1個審批環(huán)節(jié)都有可能會有審批通過,、不通過2種情況,。審批不通過時,一般是回退到上一個環(huán)節(jié),,但是在某些情況下,,有可能跨環(huán)節(jié)回退,而到底回退到哪個環(huán)節(jié),,可以由用戶根據(jù)業(yè)務需求進行自定義,,并且在回退環(huán)節(jié)工作完成之后,其下一步的方向也可以由用戶自定義,。下面根據(jù)各種不同的回退分別模擬并給出解決思路,。
3.3.1 串行流程
串行流程,最直接的方式就是在需要回退的各個節(jié)點之間建立回退線,,如圖2所示,。如果需要從節(jié)點4回退到節(jié)點2,,則直接在節(jié)點4之后加1個分支決策節(jié)點,,連接2個分支,1個是流向節(jié)點5,,1個是返回節(jié)點2,。
對于節(jié)點2,在jBPM4中,,其參與模式又分為4種:task-assignee(assignee user,、assignee expression)、task candidates(candidate-groups,、candidate-users),、task assignment handler、task swimlanes,。
(1)task-assignee任務的辦理人的值可以直接指向1個特指的用戶的ID或者1個關(guān)聯(lián)到業(yè)務中某個特指用戶的表達式(如order.owner),。此時,如果assignee賦予了1個特指用戶的ID,,回退時不用做任何處理,;如果assignee賦予了1個業(yè)務表達式,在回退時,,需要保證業(yè)務表達式的運算邏輯能夠正確執(zhí)行,。
(2)如果task candidates任務的辦理人為幾個特定的組的集合或者用戶的集合,,實際上就是俗稱的“競辦”。這樣的任務被稱為groupTask,,必須被某一個組或者用戶拾取才能進行辦理,,因此,如果回退到這樣的節(jié)點時,,需要把任務回退給當時的拾取人,。而拾取人需要到HistoryTask和HistoryDetailImpl 2個實體對應的歷史庫中取得。
(3)task assignment handler任務的辦理人通過用戶自己編寫的代碼來實現(xiàn),,當回退到這樣的節(jié)點時,,也不需要做特殊處理,只要保證自己的代碼(AssignmentHandler)在執(zhí)行回退邏輯時同樣能夠正確執(zhí)行即可,。
(4)task swimlanes任務的辦理人為“泳道”,,回退到這樣的節(jié)點時,任務的辦理人可以自動取得,,同樣不需要做任何處理,。
以上4種情況,在回退之后的處理又分為2種情況:一種是按照原來的路徑重新執(zhí)行,,即節(jié)點2→節(jié)點3→節(jié)點4,;另一種是,節(jié)點2辦理完畢后,,直接返回給節(jié)點4,。對于第1種情況,不需要做處理,。而對于第2種情況,,由于在節(jié)點2和節(jié)點4之間并沒有一個轉(zhuǎn)移存在,因此jBPM4也沒有提供支持,。針對這種情況可以通過動態(tài)路由(即動態(tài)創(chuàng)建轉(zhuǎn)移)的思路來實現(xiàn)(具體實現(xiàn)思路見第4節(jié)),,實際上回退也可以用動態(tài)創(chuàng)建轉(zhuǎn)移來實現(xiàn),但不用畫回退線了,。
3.3.2 M選N分支流程
M選N分支流程中,,N必須滿足M>N?叟1,假設(shè)回退前流程的執(zhí)行路徑為節(jié)點1→節(jié)點2→節(jié)點4→節(jié)點5,,如圖3所示,此時回退有2種情況:
(1)由節(jié)點5回退到節(jié)點1,,而節(jié)點1在進行業(yè)務數(shù)據(jù)的修改后,,直接返回給節(jié)點5的處理人進行辦理或?qū)徟?br />
(2)由節(jié)點5回退到節(jié)點1,而節(jié)點1在進行業(yè)務數(shù)據(jù)的修改后,,重新按照節(jié)點1→節(jié)點2→節(jié)點4→節(jié)點5的路徑再執(zhí)行1遍,。
情況(2)與情況(1)不同的是:在回退之后繼續(xù)審批時,,需要考慮分支節(jié)點的決策條件,在自動決策時要保證決策邏輯正確執(zhí)行,;在人工決策時,,需要記錄原來的執(zhí)行路徑(保證重走節(jié)點1→節(jié)點2→節(jié)點4→節(jié)點5)。
3.3.3 同步分裂,、“與”匯聚流程
同步分裂,、“與”匯聚流程如圖4所示,回退前執(zhí)行的路徑為節(jié)點1→節(jié)點2→(節(jié)點3,、節(jié)點4)→節(jié)點5→節(jié)點6,。此時回退有4種不同的情況:
(1)由節(jié)點6(或節(jié)點5)回退到節(jié)點2(或節(jié)點1),節(jié)點2重新辦理完畢后,,直接返回給節(jié)點6的處理人進行辦理或?qū)徟?br />
(2)由節(jié)點6(或節(jié)點5)回退到節(jié)點2(或節(jié)點1),,節(jié)點2重新辦理完畢后,重新按照節(jié)點2→(節(jié)點3,、節(jié)點4)→節(jié)點5→節(jié)點6的路徑再次執(zhí)行1遍,。
(3)由節(jié)點6(或節(jié)點5)回退到節(jié)點3(或節(jié)點4),節(jié)點3(或節(jié)點4)辦理完畢后,,直接返回給節(jié)點6,。
(4)由節(jié)點6(或節(jié)點5)回退到節(jié)點3(或節(jié)點4),節(jié)點3(或節(jié)點4)辦理完畢后,,按照節(jié)點3(或節(jié)點4)→節(jié)點5→節(jié)點6的執(zhí)行路徑,,再次執(zhí)行。
情況(1),、(2)和(3)處理起來沒有什么問題,。但情況4中,當流程由節(jié)點6回退到節(jié)點3,,節(jié)點3辦理完畢后,,重走路徑節(jié)點3→節(jié)點5→節(jié)點6時,在“與節(jié)點”的“與”運算邏輯就會無法執(zhí)行,,因為另1個“與”分支(節(jié)點4)并沒有新的實例產(chǎn)生,,流程就會僵死此處。所以可以通過修改JoinActivity.java這個類文件中的方法:
protected boolean isComplete(List<executionimpl> joined
Executions,,Activity activity)
在此方法中加入對該情況的處理代碼即可,。
3.3.4 同步分裂、“或”匯聚流程
同步分裂,、“或”匯聚流程如圖5所示,,回退前執(zhí)行的路徑為節(jié)點1→節(jié)點2→(節(jié)點3、節(jié)點4)→節(jié)點5→節(jié)點6,。此時回退同樣有4種不同的情況:
(1)由節(jié)點6(或節(jié)點5)回退到節(jié)點2(或節(jié)點1),,節(jié)點2重新辦理完畢后,,直接返回給節(jié)點6的處理人進行辦理或?qū)徟?br />
(2)由節(jié)點6(或節(jié)點5)回退到節(jié)點2(或節(jié)點1),節(jié)點2重新辦理完畢后,,重新按照節(jié)點2→(節(jié)點3,、節(jié)點4)→節(jié)點5→節(jié)點6的路徑再次執(zhí)行1遍。
(3)由節(jié)點6(或節(jié)點5)回退到節(jié)點3(或節(jié)點4),,節(jié)點3(或節(jié)點4)辦理完畢后,,直接返回給節(jié)點6。
(4)由節(jié)點6(或節(jié)點5)回退到節(jié)點3(或節(jié)點4),,節(jié)點3(或節(jié)點4)辦理完畢后,,按照節(jié)點3→節(jié)點5→節(jié)點6的執(zhí)行路徑,再次執(zhí)行,。
由于是“或”匯聚,,因此在實現(xiàn)上不需要做任何其他處理了。
綜合以上情況,,回退本身在理論上有各種各樣的情況存在,,再加上業(yè)務的回退(或者業(yè)務邏輯補償,如果需要就必須在流程的每個環(huán)節(jié)進行業(yè)務快照的備份,,在回退時調(diào)用這個快照進行補償),,此時回退可以說是整個流程體系中最復雜的。但是在真實的業(yè)務情況中,,有些可能是根本不會出現(xiàn)或者很少出現(xiàn),,因此要考慮的是能不能通過變通的方式處理。
4 動態(tài)路由的思路
針對于特定的業(yè)務實例,,有時需要在原本沒有轉(zhuǎn)移關(guān)系的環(huán)節(jié)之間進行特定的跳轉(zhuǎn),,例如在圖1中的串行流程中(1-2-3-4-5),節(jié)點4與節(jié)點2之間是沒有任何轉(zhuǎn)移存在的,,但是針對于某個運行期的特定業(yè)務實例,,臨時要求環(huán)節(jié)直接從節(jié)點4回退跳轉(zhuǎn)到節(jié)點2(而略過了節(jié)點3)。此時就需要在節(jié)點4和節(jié)點2之間由程序動態(tài)地創(chuàng)建一個轉(zhuǎn)移(transition),,并設(shè)定為優(yōu)先級最高,,如圖6所示。
因此在執(zhí)行takeTransition( )方法時,,按照優(yōu)先級將優(yōu)先執(zhí)行動態(tài)創(chuàng)建的轉(zhuǎn)移,,然后對外暴露1個jumpTransition(String destinationActivityName)方法給客戶端。應用jBPM4實現(xiàn)時可按照如下步驟進行擴展:
(1)參照文件CompleteTaskCmd.java擴展開發(fā)用于跳轉(zhuǎn)的cmd:JumpTaskCmd,。
(2)參照文件TransitionStartActivity.java的原子操作,,定制開發(fā)用于跳轉(zhuǎn)的原子操作JumpTransitionStartActivity。
由于jBPM4中的執(zhí)行動作都是基于Command模式實現(xiàn)的,,因此在擴展開發(fā)自己的跳轉(zhuǎn)動作時,,就可以做到對jBPM4本身的代碼不做侵入修改而實現(xiàn)。這種臨時建立動態(tài)路由的思路不僅可以用于回退,,同樣可以用于重新操作后的跳轉(zhuǎn)的實現(xiàn),。
jBPM作為目前應用最廣泛的開源工作流產(chǎn)品,其最新的第4版有著很好的架構(gòu)及擴展性,。但是由于國外的流程應用與國內(nèi)的應用有所不同,,因此要想讓jBPM4更好地滿足國內(nèi)的流程應用的需求,還需要做一定的定制開發(fā),。本文針對國內(nèi)的流程應用的典型特點進行了較詳細的分析,,特別針對臨時動態(tài)性需求的各種情況,給出了基于jBPM4的解決思路(限于篇幅文中并沒有給出很詳細的可以運行的代碼),。本文所做的工作只是工作流應用技術(shù)研究的一小部分,,還有很多方面需要繼續(xù)學習和實踐,需要進行深入的研究,。
參考文獻
[1] 范玉順.工作流管理技術(shù)基礎(chǔ)[M].北京:清華大學出版社,,2001.
[2] WfMC-TC00-1003v1. 1. The workflow reference model[S]. 1995.
[3] JBoss官方.jBPM Documentation[EB/OL].http://www.jboss.org/jbossjbpm.2009-09.
[4] 胡長城.工作流講解[EB/OL].www.javafox.org.2009-09.