2007-04-16?? 版權(quán)聲明
我知道這篇文章閱讀量很大,但是請要繼續(xù)轉(zhuǎn)載本文的同志注意一下,本文是我于 2005 年中旬在成都麥柯系統(tǒng)集成有限公司寫的,作為公司的技術(shù)探索并希望應(yīng)用在公司 OA 產(chǎn)品中。請保留原文版權(quán)信息 OK?
----------------------------------------------------------------------------------------------
前 言
??? 本文沒有拋出可運(yùn)行的范例,僅僅是程序片斷而已,不過在 OSWorkflow 的 Wiki 上,Quake Wang 已把官方入門教程完整地翻譯成中文了,有興趣的讀者可去閱讀。關(guān)于 OSWorkflow 更加細(xì)節(jié)性的內(nèi)容,可參考官方手冊,相信你在了解了入門教程后,可輕松閱讀官方手冊。??? OSWorkflow 概念
??? 在商用和開源世界里,OSWorkflow 都不同于這些已有的工作流系統(tǒng)。最大不同在于 OSWorkflow 有著非常優(yōu)秀的靈活性。在開始接觸 OSWorkflow 時(shí)可能較難掌握(有人說不適合工作流新手入門),比如,OSWorkflow 不要求圖形化工具來開發(fā)工作流,而推薦手工編寫 xml 格式的工作流程描述符。它能為應(yīng)用程序開發(fā)者提供集成,也能與現(xiàn)有的代碼和數(shù)據(jù)庫進(jìn)行集成。這一切似乎給正在尋找快速“即插即用”工作流解決方案的人制造了麻煩,但研究發(fā)現(xiàn),那些“即插即用”方案也不能在一個成熟的應(yīng)用程序中提供足夠的靈活性來實(shí)現(xiàn)所有需求。??? OSWorkflow 優(yōu)勢
??? OSWorkflow 給你絕對的靈活性。OSWorkflow 被認(rèn)為是一種“低級別”工作流實(shí)現(xiàn)。與其他工作流系統(tǒng)能用圖標(biāo)表現(xiàn)“l(fā)oops(回路)”和“conditions(條件)”相比,OSWorkflow 只是手工“編碼(coded)”來實(shí)現(xiàn)的。但這并不能說實(shí)際的代碼是需要完全手工編碼的,腳本語言能勝任這種情形。OSWorkflow 不希望一個非技術(shù)用戶修改工作流程,雖然一些其他工作流系統(tǒng)提供了簡單的 GUI 用于工作流編輯,但像這樣改變工作流,通常會破壞這些應(yīng)用。所以,進(jìn)行工作流調(diào)整的最佳人選是開發(fā)人員,他們知道該怎么改變。不過,在最新的版本中,OSWorkflow 也提供了 GUI 設(shè)計(jì)器來協(xié)助工作流的編輯。
??? OSWorkflow 基于有限狀態(tài)機(jī)概念。每個 state 由 step ID 和 status 聯(lián)合表現(xiàn)(可簡單理解為 step 及其 status 表示有限狀態(tài)機(jī)的 state)。一個 state 到另一 state 的 transition 依賴于 action 的發(fā)生,在工作流生命期內(nèi)有至少一個或多個活動的 state。這些簡單概念展現(xiàn)了 OSWorkflow 引擎的核心思想,并允許一個簡單 XML 文件解釋工作流業(yè)務(wù)流程。
OSWorkflow 核心概念 ??? step(步驟)??? 一個 step 是工作流所處的位置。可能從一個 step 流轉(zhuǎn)到另外一個 step(或者有時(shí)候還是停留在一樣的 step)。舉例來說,一個 OA 系統(tǒng)的請假流程,它的 step 名稱可能有“本部門審批階段”,“辦公室審批階段”,“總經(jīng)理審批階段”等。?status(狀態(tài))??? 工作流 status 是一個用來描述工作流程中具體步驟狀態(tài)的字符串。OSWorkflow 的有 Underway(進(jìn)行中)、Queued(等候處理中)、Finished(完成)三種 status。?action(動作)??? action 指定了可能發(fā)生在 step 內(nèi)的轉(zhuǎn)變,會導(dǎo)致 step 的變更。在 OA 系統(tǒng)中,“本部門審批階段”可能有“拒絕”或“批準(zhǔn)”兩個 action。action 和 step 之間的關(guān)系是,step 說明“在哪里”,action 說明“可以去哪里”。 一個 action 典型地由兩部分組成:可以執(zhí)行此動作的 condition(條件),以及執(zhí)行此動作的 result(結(jié)果)。?condition(條件)??? 類似于邏輯判斷,可包含“AND”和“OR”邏輯。比如一個請假流程中的“本部門審批階段”,該階段利用“AND”邏輯,判斷流程狀態(tài)是否為等候處理中,以及審批者是否為本部門主管。??? result(結(jié)果)??? Result 代表指向新的 step 及其 step status,也可能進(jìn)入 split 或者 join。Result 分為兩種, contidional-result (有條件結(jié)果),只有條件為真時(shí)才使用該結(jié)果,和 unconditional-result(無條件結(jié)果),當(dāng)條件不滿足或沒有條件時(shí)使用該結(jié)果。
split/join(分離/連接) 流程的切分和融合。很簡單的概念,split 提供多個 result;join 則判斷多個 current step 的狀態(tài),提供一個 result。
OSWorkflow 包用途分析及代碼片斷 ??? com.opensymphony.workflow??? 該包為整個 OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口,可以說,實(shí)際開發(fā)中的大部分工作都是圍繞該接口展開的,該接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三個實(shí)現(xiàn)類。
com.opensymphony.workflow.basic ??? 該包有兩個類,BasicWorkflow 與 BasicWorkflowContext。BasicWorkflow 不支持事務(wù),盡管依賴持久實(shí)現(xiàn),事務(wù)也不能包裹它。BasicWorkflowContext 在實(shí)際開發(fā)中很少使用。
com.opensymphony.workflow.config ??? 該包有一個接口和兩個該接口的實(shí)現(xiàn)類。在 OSWorkflow 2.7 以前,狀態(tài)由多個地方的靜態(tài)字段維護(hù),這種方式很方便,但是有很多缺陷和約束。最主要的缺點(diǎn)是無法通過不同配置運(yùn)行多個 OSWorkflow 實(shí)例。實(shí)現(xiàn)類 DefaultConfiguration 用于一般的配置文件載入。而 SpringConfiguration 則是讓 Spring 容器管理配置信息。
com.opensymphony.workflow.ejb ??? 該包有兩個接口 WorkflowHome 和 WorkflowRemote。該包的若干類中,最重要的是 EJBWorkflow,該類和 BasicWorkflow 的作用一樣,是 OSWorkflow 的核心,并利用 EJB 容器管理事務(wù),也作為工作流 session bean 的包裝器。
com.opensymphony.workflow.loader ??? 該包有若干類,用得最多的是 XxxxDescriptor,如果在工作流引擎運(yùn)行時(shí)需要了解指定的動作、步驟的狀態(tài)、名字,等信息時(shí),這些描述符會起到很大作用。
com.opensymphony.workflow.ofbiz ??? OfbizWorkflow 和 BasicWorkflow 在很多方面非常相似,除了需要調(diào)用 ofbiz 的 TransactionUtil 來包裝事務(wù)。
com.opensymphony.workflow.query ??? 該包主要為查詢而設(shè)計(jì),但不是所有的工作流存儲都支持查詢。通常,Hibernate 和 JDBC 都支持,而內(nèi)存工作流存儲不支持。值得注意的是 Hibernate 存儲不支持混合型查詢(例如,一個查詢同時(shí)包含了 history step 上下文和 current step 上下文)。執(zhí)行一個查詢,需要創(chuàng)建 WorkflowExpressionQuery 實(shí)例,接著調(diào)用 Workflow 對象的 query 方法來得到最終查詢結(jié)果。
??public List queryDepAdmin(int userId,int type) {??int[] arr = getSubPerson(userId,type);
??//構(gòu)造表達(dá)式??Expression[] expressions = new Expression[1 + arr.length];??Expression expStatus = new FieldExpression(FieldExpression.STATUS,????FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");??expressions[0] = expStatus;
??for (int i = 0; i < arr.length; i++) {???Expression expOwner = new FieldExpression(FieldExpression.OWNER,?????FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,?????Integer.toString(arr[i]));???expressions[i + 1] = expOwner;??}
??//查詢未完成流編號??List wfIdList = null;??try {???WorkflowExpressionQuery query = new WorkflowExpressionQuery(?????new NestedExpression(expressions, NestedExpression.AND));???wfIdList = workflow.query(query);??} catch (Exception e) {???e.printStackTrace();??}
com.opensymphony.workflow.spi ??? 該包可以說是 OSWorkflow 與持久層打交道的途徑,如當(dāng)前工作流的實(shí)體,其中包括:EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler。
com.opensymphony.workflow.util該包是 OSWorkflow 的工具包,包括了對 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持。
小 結(jié)
??? 由于本人所在公司希望在 OA 系統(tǒng)中引入工作流引擎,經(jīng)過分析決定采用 OSWorkflow 引擎。利用 OSWorkflow,已經(jīng)在系統(tǒng)中實(shí)現(xiàn)了請假條流程原型,該流程結(jié)合 OA 系統(tǒng)中已有的 RBAC 模型進(jìn)行逐級審核。我個人認(rèn)為要用 OSWorkflow 讓某個流程跑起來似乎很麻煩,主要是需要擴(kuò)展和自己實(shí)現(xiàn)的太多。??? ??? 另外,引用一段 Quake Wang 的原話:電子政務(wù)/OA 如果要使用workflow engine的話,shark,jbpm 之類的workflow engine有點(diǎn)殺雞用牛刀的味道。shark 和 jbpm 都強(qiáng)迫你使用它的用戶模型,怎樣把企業(yè)現(xiàn)有的用戶模型(包括組織結(jié)構(gòu))映射過來是很繁瑣的事情,比如常見的 OA 應(yīng)用中,申請者對應(yīng)的部門負(fù)責(zé)人為下一個流程的人工參與者,使用 shark 或者 jbpm 都得繞一圈,通過現(xiàn)有的人力資源系統(tǒng),獲得用戶,再對應(yīng)過來。這還僅僅是一個簡單的需求,更不用說國內(nèi)企業(yè)千奇百怪的組織結(jié)構(gòu),以及各種特殊流程,用 wfmc 或者其他所謂的 workflow 通用標(biāo)準(zhǔn)去做不怎么標(biāo)準(zhǔn)的事情。吃力不討好。用 osworkflow 這種基于狀態(tài)機(jī)的 workflow engine 反而會輕松很多,而且它也沒有強(qiáng)迫你使用它的用戶模型。另外糾正一點(diǎn):osworkflow 不僅僅支持簡單的 BeanShell,還支持 java class,bsf,ejb。如果做電子政務(wù)/OA 的話,覺得目前 osworkflow 是最適用的 opensource workflow engine。請注意!引用、轉(zhuǎn)貼本文應(yīng)注明原作者:Rosen Jiang 以及出處:http://www.tkk7.com/rosen
Powered by: BlogJava Copyright © Rosen