Workflow JBPM 工作流

2009-03-10 19:57

準備學習開源的工作流,這是我在別人日記上找的,介紹得很不錯。跟大家一起分享。
一、工作概述
主要的工作時間花在以下幾個方面,它們也是學習、研究工作流的一般途徑:
1、JBPM3.2.1官方UserGuide(21章)通讀了幾遍,包括官方的examples、forum、wiki、apidoc。這五份資料來源是我認爲最重要的。
2、google(english)、Javaeye和csdn相關工作流技術文章和評論,特別是“銀狐999”的工作流blog。
3、國內OA、工作流、BPM產品的演示和功能介紹,如joinwork,思維加速,西安協同,摩卡等。
4、xflow、osworkflow、Willow、agileFlow等國內外開源工作流了解。
5、幾本重要的工作流、BPM相關書籍和workflow模式,最重要的兩本書是《OReilly Essential Business Process Modeling》、《MIT Press - Workflow Management--Models, Methods & Systems》。 另外JBPM的UserGuide第四章Graph Oriented Programming裏有一個jbpm.gop.zip下載包,它就是JBPM引擎的mini版,幾乎涵蓋有JBPM引擎的絕大部分,如流轉、分支、合併、、並行、同步、異步、事件、Action、表單。
6、JBPM的一個請假流程從頁面到持久化的整個demo開發(約花兩週時間),例子來源於csdn上一個非常典型的例子,有順序、併發、互斥、條件分支等情形。另外,特別針對JBPM源碼進行跟蹤調試(四天)。
7、對當前項目的若干Use Case的深入分析,如流程圖表示、流程實現。
二、JBPM環境和開發
JBPM開發環境JBPM我是從3.1.4版本開始研究的,但發現3.1.4版的designer在推薦的eclipse3.12下畫流程圖時,eclipse總是處理僵死狀態,一個操作都要5s以上。無奈之下,下載JBPM3.2版本,該版本在eclipse3.1.2下designer無法正常使用。但在eclipse3.3,也就是官方剛出來的Europa版本下,其designer可以正常使用,但代碼開發時,也是僵死狀態,而在eclipse3.12下開發正常。所以,我現在的做法是,用JBPM的3.2.1版本,用eclipse的3.12做開發和調試,用eclipse3.3做流程可視化設計。另外,3.2.1對mail這類節點有支持。
JBPM控制檯
JBPM的管理控制檯從3.1.4到3.2.1有非常大的改進,如中文問題、界面、流程發佈等。但在實際項目中,我們還是幾乎無法使用,理由如下:
1、該管理控制檯還是很粗糙,只有最基本的功能,沒有權限、組織結構、細粒度的流程管理等功能,另外必須漢化。
2、其流程designer默認是生成JSF表單,也就是說整個管理控制檯和流程開發最方便是JSF做表示層,這不符合我們當前的項目實際。另外,用自己的業務表,而不是JBPM自帶的活表(數據庫對應jbpm_variableinstance表),也就意味着JSF表單沒法用上。
3、我們的流程存在大量中國特色的定製,如回退、臨時流轉、跳越,不可能將流程用JBPM的designer設計好,發佈到控制檯就ok這麼簡單。
當前,我們的項目需要流程控制檯,但應該是完全自己開發,可以借鑑JBPM後臺的設計實現思想,特別是流程查看時的流程圖顯示;另外我們還需要table格式的詳細流轉過程。
一般來說,控制檯做得很強大的工作流系統,都是standalone方式運行,而不是我們現在的embeded方式。
關於JBPM控制檯入門知識,JBPM官方wiki有非常詳細的介紹。
JBPM的開發模式
實際的JBPM開發,我覺得應該注意以下幾個問題:
1、業務處理的位置 我們知道,在MIS系統,如OA項目中引入工作流,主要是將流程邏輯和業務邏輯分開,流程數據持久化到流程引擎表,業務數據持久化到業務表。這就涉及到業務邏輯在哪裏處理的問題。在JBPM中,是在ActionHandler還是在Business Service中?
ActionHandler中:我們將業務在JBPM的回調接口ActionHandler實現中處理,將業務表單對象通過ContextInstance的setTransientVariables()傳入,在ActionHandler中持久化,也就是說,ActionHandler是我們的業務處理主體,可以通過在Task實例中記錄業務表單ID。另外,數據庫的Connection可以通過ActionHandler的ExecuteContext參數取得。
Business Service中:這個Service就對應於用Spring框架時的Service,我們可以在service方法裏面調用JBPM的API,如JbpmConfiguration.getInstance().createJbpmContext(); TaskInstance ti = jContext.getTaskInstance(tiid); 將業務數據都持久化到JBPM的活表裏,這樣只在一個數據庫Conntection上,可以避免分佈式事務的問題。
上面兩種方式,第一種是我推薦的,其基本思想是將工作流引擎當成一個集成框架,一切以流程爲主線。第二種是將工作流引擎當成輔助的第三方庫。兩種方式對系統的侵入性都非常大,無侵入性我認爲不現實。
參考:
http://www.processdriven.org/process_liberation.html
http://weblogs.java.net/blog/edgars/archive/2007/08/understanding_j_1.html
2、業務數據的存儲 把業務數據持久化到JBPM的活表jbpm_variableinstance中,可以很容易地進行字段級別的權限控制,靈活的表單自定義,而且可以在JBPM的管理控制檯上二次開發,將開發的工作量降到最低,而這是大多數商業工作流產品實現的目標。但是,活表對於實時的業務報表統計分析很低效,有時不可能,因爲表單項是離散的,並且不是最重要的關注點。關注點可能是流程的執行效率統計,也就是流程數據統計。
成熟的工作流管理系統(工作流引擎只是其中一個組成部分)往往是一個任務或節點對應一個表單,這樣很便於表單自定義,將流程設計、表單定義、權限控制、組織結構和任務分配一氣呵成。我理解的表單,只是如同Struts裏面的ActionForm,只是頁面數據的收集和呈現形式,具體到這些表單怎麼持久化,採用JBPM的活表或自定義的業務表均可,但我傾向後者。
3、面向流程的MIS系統的開發過程 對於一般的MIS系統開發,很強調領域分析、系統設計,也就是大量的UML圖。這樣的系統,往往可以抽象爲增刪改查CRUD,可以按頁面分配工作量,增刪改查都是無狀態的,也就是說開發“增”並不影響“改”,一個操作一個業務,各業務操作互不影響、耦合。但有清晰流程的系統就不同,每一個業務操作都是有狀態的,譬如一個OA的發文流程,可能有十來個步驟,各級領導審覈、審批、查閱,每一步的操作都影響後面的業務流向,而且必須有各業務相關人員協作才能完成該發文目標,這樣通過CRUD方式去理解這個系統就無法理清業務,如果通過流程驅動方式去建模,那麼事情就簡單了。
這樣,就引發了一個問題:流程驅動的MIS系統,怎麼制定軟件開發過程?如果大家看過工作流產品(關鍵字:工作流、OA、協同、BPM)的demo介紹,就會知道,工作流系統的開發,往往和流程設計、表單設計打交道,在我們的成果物中(RUP中是artifact、工件),沒有OO的概念,領域分析讓位於流程分析:難道我們真的需要一個請假單LeaveForm的Domain?做報表系統開發,應該也沒有強調Domain吧?因爲它是數據驅動,沒有強調業務層。
所以,我認爲,流程驅動的業務系統開發,不要將概要設計、詳細設計往上面套,它們的重點往往沒有放在流程設計和實現這個根本問題上。也許,概要設計、詳細設計這種瀑布開發過程挺適合低端的外包項目,譬如對日的外包,將低端Coding外包給中國公司。前提是,別人的詳細設計可以確定95%以上需求,需求不明確帶來的風險很小。另外,在用JBPM開發過程中,也許業務主要寫在JBPM這個框架的ActionHandler回調接口中,我們詳細設計的順序圖中的call或sendMessage,不適合反映這種過程,因爲ActionHandler的lifecycle我們無法控制。那麼詳細設計的意義何在?
那麼,軟件過程怎麼定?我認爲還是敏捷一點,只關注三點:用戶需求(詳細的用例文檔和原型)、流程設計、流程實現。文檔只集中在第一點。
我認爲,參考基於成熟的商業工作流產品開發模式,就是我們系統的開發的模式。
三、JBPM對常見流程問題的解決
JBPM的API文檔非常匱乏,但是,JBPM的源碼內部有很多註釋,其代碼可讀性非常強,核心代碼我認爲不超過1w行,引擎核心代碼也許只有兩三千行。另外,閱讀源碼,最好對UML活動圖、Petri網、Workflow模式較熟悉,譬如Join. setDiscriminator(),如果不瞭解Workflow模式的Discriminator模式,該方法就不知所措。
Process本質上,只有兩個對象:Node和Transition(節點和有向弧),只要這兩類對象就可以完整繪出一個流程圖,當然,Node有很多子類,譬如Start、End、Fork、Join、Decision等。
JBPM的過程調度,是通過Token在流程節點之間轉移實現的。譬如TaskInstance.end()的時候,調用Token.signal(),在signal()內部,依次調用:Node.leave(),Transition.take(),Node.enter(),這三個調用依次引發如下三個event:node-leave,transition,node-enter,在event內部,就處理我們自定義的ActionHandler和記日誌。從中我們可以看出,事件(event)處理和Token調度是分離的。上面的三個event是重複循環的,可以驅動流程向前進行:離開當前節點?過渡?進入下一節點。
上面就是JBPM的大致調度過程,清晰、簡潔。
參考:
JBPM引擎架構:http://blog.csdn.net/james999/archive/2007/09/02/1769592.aspx
JBPM微型架構實現:http://docs.jboss.com/jbpm/gop/jbpm.gop.zip
下面我對JBPM對工作流中常見問題的解決方案總結一下,基本上都來源於網絡,自己試驗了一下,很可行。
1、互斥任務
譬如,員工請假流程中,員工請假申請提交後,系統應該創建兩個併發任務:員工取消和主管審批,只要任何一個任務結束,另外一個就應該結束。
一種實現方式是,在請假申請Node後Fork出兩個Node,員工取消和主管審批,它們Transition 的ActionHandler裏結束另外一個Node的TaskInstance。
另外一種實現方式是,在一個Node裏創建上面兩個Task,在Node節點裏設置屬性signal="first" end-tasks="true"。signal="first"指一個任務結束,當前節點就流轉;end-tasks="true"指結束該節點時自動結束其它沒有完成的任務。
參考:http://jbpm.group.javaeye.com/group/blog/59741
2、動態創建任務,會籤或任務分派
像會籤這類動態創建任務的情形,用流程圖很難描述,所以一般是通過代碼手工創建,JBPM爲這提供了很方便的接口。
JBPM的實現方式。在task-node設置create-tasks="false",在該task-node的event-enter事件中,自定義ActionHandler,處理任務創建的工作。
說明:對JBPM的API用得得心應手,必須對其API設計實現、引擎思想有較深入理解,譬如Event機制、Token調度、Workflow模式等,其API絕對沒有Servlet API那麼簡單,容易上手。
參考:http://www.cnblogs.com/amushen/archive/2007/07/03/804237.aspx
3、循環節點,文件傳閱
在默認的JBPM的designer裏無法畫出指向自身的有向弧,可以先在該節點的XML流程定義文件裏寫出指向自身的Transition,這樣在圖形顯示下就會出現指向自身的有向弧。當然,重複創建兩個類似的節點,之間有往返有向弧也可以實現。
4、併發子流程JBPM自身對子流程的支持不夠靈活,如只能創建一個子流程(ProcessState.setSubProcessDefinition()而不是addSubProcessDefinition())
一種解決方案是用流程的Hierarchy分級結構方式,請參考:http://jeffreyhsu.javaeye.com/blog/29917
...............
...............
5、客戶的Visio流程原型實現的探討
該流程原型,要求把JBPM的流程定義模塊重新實現,有一定難度。但我認爲,實現是完全可以的,但初步實現需要一個多人月的時間(以自己目前的能力)。
作爲我個人的角度,我覺得Leader應該給開發人員充分的授權,信任開發人員,時間自由支配,定一個大致milestone就可以了。前段時間的技術調研太浮躁,一天一個方向,根本就沒有調研深度。做一件事情需要多少時間就是多少時間,人爲主觀去控制,註定會失敗的。
如果現在想按客戶的要求實現,技術比以前的預想難多了,因爲現在的流程定義是活的,相當於我們做了一個流程管理控制檯和流程設計器。可以做,但風險大,不過,靜下心來,是完全可以完成的,因爲JBPM這部分相關代碼只有幾千行(千萬不要忘了,JBPM只是一個naked流程引擎,不是工作流管理系統)。項目現在面臨的一個問題是,前期開發有一個時間瓶頸,核心代碼沒有開發出來,後面的開發無法進行,以當前的管理模式,勢必會讓前期開發人員浮躁(自由的思想纔會有深度,有創造力)。
客戶原型實現看法:
流程定義和修改:JBPM有JpdlXmlReader,負責XML流程定義解析的,把該類和其關聯類弄明白就差不多了,估計約兩天時間,我花完整一天時間讀過,不太難。
節點編輯,出口編輯:解析過程同上,
數據項編輯:利用JBPM自己的活表(TaskController相關),實現不是很難。
如果按客戶的方式做,做成功了,其它項目就很好複用,因爲它就是做了一個通用的元框架,也算是拿做產品的要求來做項目。
另外,如果不做成通用框架,解決現在項目中的若干技術問題難度都不大,如回退、串並行、版本控制、自由流、多子流程、強制跳轉、自定義時限、權限控制、流程監控。但“提供自定義流程功能”,就是上面客戶的要求,這個難度很大,和中棉項目自定義報表難度有的一拼(中棉項目自定義報表以失敗告終)。
就總結到這兒吧,Workflow、BPM是企業軟件的趨勢,以後還得努力啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章