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