??????????????????????????????????????
使用Spring來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的工作流引擎?????????????????????
spring是支持控制反轉(zhuǎn)編程機(jī)制的一個(gè)相對(duì)新的框架。本文把spring作為簡(jiǎn)單工作流引擎,將它用在了更加通用的地方。在對(duì)工作流簡(jiǎn)單介紹之后,將要介紹在基本工作流場(chǎng)景中基于Spring的工作流API的使用。
許多J2EE應(yīng)用程序要求在一個(gè)和主機(jī)分離的上下文中執(zhí)行處理過程。在許多情況下,這些后臺(tái)的進(jìn)程執(zhí)行多個(gè)任務(wù),一些任務(wù)依賴于以前任務(wù)的狀態(tài)。由于這些處理任務(wù)之間存在相互依賴的關(guān)系,使用一套基于過程的方法調(diào)用常常不能滿足要求。開發(fā)人員能夠利用Spring來(lái)容易地將后臺(tái)進(jìn)程分離成活動(dòng)的集合。Spring容器連接這些活動(dòng),并將它們組織成簡(jiǎn)單的工作流。
在本文中,簡(jiǎn)單工作流被定義成不需要用戶干預(yù),以一定順序執(zhí)行的任意活動(dòng)的集合。然而,我們并不建議將這種方式代替存在的工作流框架。在一些場(chǎng)景中,需要更多的用戶交互,例如基于用戶輸入而進(jìn)行的轉(zhuǎn)向,連接或傳輸,這時(shí),比較好的方法是配用一個(gè)單獨(dú)的開源或者商業(yè)的工作流引擎。一個(gè)開源項(xiàng)目已經(jīng)成功地將更復(fù)雜的工作流設(shè)計(jì)集成到spring中。
如果你手上的工作流任務(wù)是簡(jiǎn)單的,那么,與功能完備的獨(dú)立工作流框架相比,簡(jiǎn)單工作流的策略就會(huì)變得有意義,特別地,如果已經(jīng)使用了spring,這種快速實(shí)現(xiàn)可以保證時(shí)間不會(huì)變得更加漫長(zhǎng)。此外,考慮到spring輕量級(jí)的控制反轉(zhuǎn)容器的特點(diǎn),spring在資源負(fù)載上減少了資源負(fù)載。
這篇文章簡(jiǎn)短地從編程主題的角度介紹工作流。通過使用工作流的概念,spring被用來(lái)作為驅(qū)動(dòng)工作流引擎的框架。然后,討論了生產(chǎn)部署選項(xiàng)。現(xiàn)在,讓我們從工作流的設(shè)計(jì)模式和相關(guān)背景信息來(lái)介紹簡(jiǎn)單工作流的思想吧。
簡(jiǎn)單工作流
工作流模型是一個(gè)早在70年代就有人開始研究的主題,許多開發(fā)者都試圖創(chuàng)建工作流模型規(guī)范。W.H.M. van der Aalst等人寫了《工作流模型》白皮書(2003年7月),它成功地提煉出一組設(shè)計(jì)模式,這些設(shè)計(jì)模式準(zhǔn)確地將大多數(shù)通用的工作流場(chǎng)景建模。當(dāng)中,最普通的工作流模式是順序模式 (Sequence pattern)。順序工作流模式滿足了簡(jiǎn)單工作流的設(shè)計(jì)原則,并且由一組順序執(zhí)行的活動(dòng)組成。
UML(統(tǒng)一建模語(yǔ)言)活動(dòng)圖通常被用來(lái)作為一個(gè)機(jī)制對(duì)工作流建模。圖1顯示了一個(gè)基本的使用標(biāo)準(zhǔn)UML活動(dòng)圖對(duì)順序工作流過程的建模過程。
圖 1順序工作流模式
順序工作流是一個(gè)在J2EE中流行的標(biāo)準(zhǔn)工作流模式。J2EE應(yīng)用程序在后臺(tái)線程中,通常需要一些順序發(fā)生的事件或者異步事件。圖2中的活動(dòng)圖描述了一個(gè)簡(jiǎn)單的工作流,用來(lái)通知感興趣的旅行者,他們感興趣的目的地的機(jī)票價(jià)格已經(jīng)下降的事件。
圖 2.機(jī)票價(jià)格下降的簡(jiǎn)單工作流
- 作者: macrochen 2005年12月11日, 星期日 22:28
圖1中的航線工作流負(fù)責(zé)創(chuàng)建和發(fā)送動(dòng)態(tài)的email通知。過程中的每一步表示了一個(gè)活動(dòng)(activity)。在工作流處于活動(dòng)之前,一些額外事件必須發(fā)生。在這個(gè)例子中,事件是飛行路線費(fèi)率的減少。
讓我們來(lái)簡(jiǎn)要的看一下航線工作流的業(yè)務(wù)邏輯。如果第一個(gè)活動(dòng)找不到對(duì)費(fèi)率減少通知感興趣的用戶,那么整個(gè)工作流就被取消。如果發(fā)現(xiàn)了感興趣的用戶,那么接下來(lái)的活動(dòng)繼續(xù)執(zhí)行。隨后,一個(gè)XSL(擴(kuò)展樣式表)轉(zhuǎn)換生成消息內(nèi)容,之后,記錄審計(jì)信息 (audit information)。最后,工作流試圖通過SMTP服務(wù)器發(fā)送這個(gè)消息。如果這個(gè)任務(wù)沒有錯(cuò)誤地完成,便在日志中記錄成功的信息,進(jìn)程結(jié)束。但是,如果在和SMTP服務(wù)器通訊時(shí)發(fā)生了錯(cuò)誤,一個(gè)特別的錯(cuò)誤處理例程將要管理這些錯(cuò)誤。錯(cuò)誤處理代碼將會(huì)試著去重新發(fā)送消息。
考慮這個(gè)航線的例子,一個(gè)明顯的問題是:你怎么樣有效地將順序處理過程分解為單獨(dú)的活動(dòng)?這個(gè)問題被spring巧妙的處理了。下面,讓我們快速地討論spring的反轉(zhuǎn)控制框架。
控制反轉(zhuǎn)
Spring通過使用spring容器來(lái)負(fù)責(zé)控制對(duì)象之間的依賴關(guān)系,使得我們不再對(duì)對(duì)象之間的依賴負(fù)責(zé)。 這種依賴關(guān)系的實(shí)現(xiàn)就是大家所知道的控制反轉(zhuǎn)(IoC)或依賴注射。參見Martin Fowler's "Inversion of Control Containers and the Dependency Injection Pattern"(martinfowler.com, 2004年2月)得到關(guān)于控制反轉(zhuǎn)和依賴注射的更加深入的討論。通過管理對(duì)象之間的依賴關(guān)系,spring就不需要那些只是為了使類能夠相互協(xié)作,而將對(duì)象粘合的代碼。
作為spring beans的工作流組件
在進(jìn)一步討論之前,現(xiàn)在是簡(jiǎn)要介紹spring中主要概念的恰當(dāng)時(shí)候。接口ApplicationContext是從接口BeanFactory繼承的,它被用來(lái)作為在spring容器內(nèi)實(shí)際的控制實(shí)體和容器。
ApplicationContext負(fù)責(zé)對(duì)一組作為spring beans的一組bean的初始化,配置和生命期管理。我們通過裝配在一個(gè)基于XML的配置文件中的spring beans來(lái)配置ApplicationContext。這個(gè)配置文件說明了spring beans互相協(xié)作的本質(zhì)特點(diǎn)。這樣,用spring的術(shù)語(yǔ)來(lái)說,與其他spring beans交互的spring beans就被叫著協(xié)作者(collaborators)。缺省情況下,spring beans是作為單例存在于ApplicationContext中的,但是,單例的屬性能夠被設(shè)置為false,從而有效地改變他們?cè)趕pring中調(diào)用原型模式時(shí)的行為。
回到我們的例子,在飛機(jī)票價(jià)下降的時(shí)候,一個(gè)SMTP發(fā)送例程的抽象就被裝配在工作流過程例子中的最后的活動(dòng)(例子代碼可以在 Resources中得到)。由于是第5個(gè)活動(dòng),我們命名它為activity5。要發(fā)送消息,activity5就要求一個(gè)代理協(xié)作者和一個(gè)錯(cuò)位處理句柄。
????? class="org.iocworkflow.test.sequence.ratedrop.SendMessage">
?????
???????? BR>?????
?????
????????
?????
??
將工作流組件實(shí)施成spring beans產(chǎn)生了兩個(gè)令人喜悅的結(jié)果,就是容易進(jìn)行單元測(cè)試和很大程度上可重用能力。IoC容器的特點(diǎn)明顯地提供了有效的單元測(cè)試。使用像spring這樣的Ioc容器,在測(cè)試期間,協(xié)作者之間的依賴能夠容易的用假的替代者替代。在這個(gè)航線的例子中,能夠容易地從唯一的測(cè)試ApplicationContext中檢索出像activity5活動(dòng)這樣的spring bean。用一個(gè)假的SMTP代理SMTP服務(wù)器,就有可能單獨(dú)地測(cè)試activity5。
第二個(gè)意外的結(jié)果,可重用能力是通過像XSL轉(zhuǎn)換這樣的工作流活動(dòng)實(shí)現(xiàn)的。一個(gè)被抽象成工作流活動(dòng)的XSL轉(zhuǎn)換現(xiàn)在能夠被任何處理XSL轉(zhuǎn)換的工作流所重用。
裝配工作流
在提供的API中(從Resources下載),spring控制了一些操作者以一種工作流的方式交互。關(guān)鍵接口如下:
Activity: 封裝了工作流中一個(gè)單步業(yè)務(wù)邏輯
ProcessContext:在工作流活動(dòng)之間傳遞具有ProcessContext類型的對(duì)象。實(shí)現(xiàn)了這個(gè)接口的對(duì)象負(fù)責(zé)維護(hù)對(duì)象在工作流轉(zhuǎn)換中從一個(gè)活動(dòng)轉(zhuǎn)換到另一個(gè)活動(dòng)的狀態(tài)。
ErrorHandler: 提供錯(cuò)誤處理的回調(diào)方法。
Processor: 描述一個(gè)作為主工作流線程的執(zhí)行者的bean。
下面從例子源碼中摘錄的代碼是將航線例子裝配為簡(jiǎn)單工作流過程的spring bean的配置。
??
?????
????????
???????????
???????????
???????????
???????????
???????????
???????? BR>?????
?????
???????? BR>????? /property>
?????
????????
?? /property>
SequenceProcessor類是一個(gè)對(duì)順序模式建模的具體子類。有5個(gè)活動(dòng)被連接到工作流處理器,工作流處理器將順序執(zhí)行這5個(gè)活動(dòng)。
與大多數(shù)過程式后臺(tái)進(jìn)程相比,工作流的解決方案真正的突出了高度強(qiáng)壯的錯(cuò)誤處理。錯(cuò)誤處理句柄可以單獨(dú)地處理每個(gè)活動(dòng)。這種類型的句柄在單一活動(dòng)級(jí)別提供了細(xì)致的錯(cuò)誤處理。如果沒有單獨(dú)處理單個(gè)活動(dòng)的錯(cuò)誤處理句柄,那么全局工作流處理器的錯(cuò)誤處理句柄將會(huì)處理出現(xiàn)的問題。例如,如果在工作流處理過程中的任意時(shí)刻,一個(gè)沒有被處理的錯(cuò)誤出現(xiàn)了,那么它將會(huì)向外傳播,被使用defaultErrorHandler屬性裝配的ErrorHandler Bean處理。
更復(fù)雜的工作流框架將工作流轉(zhuǎn)換之間的狀態(tài)持久化存儲(chǔ)到數(shù)據(jù)庫(kù)中。在這篇文章中,我們僅僅對(duì)狀態(tài)轉(zhuǎn)換是自動(dòng)完成的工作流感興趣。狀態(tài)信息僅僅在實(shí)際工作流運(yùn)行時(shí)在ProcessContext中得到。在ProcessContext中,你僅僅能看到ProcessContext的接口的兩個(gè)方法:
public interface ProcessContext extends Serializable {
????? public boolean stopProcess();???
????? public void setSeedData(Object seedObject);
?? }
用于航線例子工作流的具體的ProcessContext類是RateDropContext類。RateDropContext類封裝了用于執(zhí)行航線費(fèi)率降低工作流必須的數(shù)據(jù)。
到現(xiàn)在為止,經(jīng)由缺省的ApplicationContext的作用,所有bean實(shí)例都已經(jīng)成了單例。但是,對(duì)于每一個(gè)航線工作流的調(diào)用,我們必須創(chuàng)建一個(gè)新的RateDropContext類的實(shí)例。為了處理這種需求,需要配置SequenceProcessor,采用全限定類名作為processContextClass屬性的值。對(duì)于每個(gè)工作流的執(zhí)行,SequenceProcessor使用指定的類名從spring檢索ProcessorContext類的一個(gè)新的實(shí)例。為了使這種機(jī)制能夠起作用,非單件的spring bean或者類型org.iocworkflow.test.sequence.simple.SimpleContext的原型必須存在于ApplicationContext中(完整的列表,參見rateDrop.xml)。
播種工作流
既然我們知道怎樣使用spring來(lái)組裝一個(gè)簡(jiǎn)單的工作流,就讓我們集中精力使用種子數(shù)據(jù)(seed data)示例工作流的過程。要明白怎樣開始工作流,看一看在實(shí)際接口Processor上表現(xiàn)的方法:
public interface Processor {
????? public boolean supports(Activity activity);
????? public void doActivities();
????? public void doActivities(Object seedData);
????? public void setActivities(List activities);
????? public void setDefaultErrorHandler(ErrorHandler defaultErrorHandler);
?? }
大多數(shù)情況下,工作流需要一些初始化激活才能開始。開始一個(gè)處理過程有兩個(gè)選項(xiàng):doActivities(ObjectseedData)方法或者無(wú)參數(shù)的doActivities()。下面的代碼列表是包含在樣例代碼中為SequenceProcessor而實(shí)現(xiàn)的doActivities():
public void doActivities(Object seedData) {
?? //Retrieve injected by Spring
?? List activities = getActivities();
?? //Retrieve a new instance of the Workflow ProcessContext
?? ProcessContext context = createContext();
?? if (seedData != null)
????? context.setSeedData(seedData);
?? //Execute each activity in sequential order
?? for (Iterator it = activities.iterator(); it.hasNext();) {
????? Activity activity = (Activity) it.next();
????? try {
??????????? context = activity.execute(context);
????? } catch (Throwable th) {
???????? //Determine if an error handler is available at the activity level
???????? ErrorHandler errorHandler = activity.getErrorHandler();
???????? if (errorHandler == null) {
??????????? getDefaultErrorHandler().handleError(context, th);
??????????? break;
???????? } else {
??????????? //Handle error using default handler
??????????? errorHandler.handleError(context, th);
???????? }
????? }
??????????? //Ensure it's ok to continue the process
????? if (processShouldStop(context, activity))
???????? break;
????? }
?? }
在這個(gè)航空費(fèi)用減少的例子中,工作流過程的種子數(shù)據(jù)包括航線信息和費(fèi)率減少的信息。使用容易測(cè)試的航線工作流例子,通過doActivities(Object seedData)方法發(fā)出種子數(shù)據(jù)并激活一個(gè)單一的工作流過程是簡(jiǎn)單的:
BaseProcessor processor = (BaseProcessor)context.getBean("rateDropProcessor");
?? processor.doActivities(createSeedData());
這些代碼是從包含在這篇文章中的測(cè)試?yán)又姓浀摹ateDropProcessor Bean是從ApplicationContext中檢索來(lái)的。rateDropProcessor實(shí)際上是裝配成SequenceProcessor的實(shí)例來(lái)處理順序執(zhí)行。createSeedData()方法實(shí)例化一個(gè)對(duì)象,這個(gè)對(duì)象封裝了初始化航線工作流所需要的所有種子數(shù)據(jù)。
Processor選項(xiàng)
雖然包含在源代碼中的Processor具體的子類僅僅是SequenceProcessor,但是,許多Processor接口的實(shí)現(xiàn)也是可以想象得到的。可以開發(fā)其他工作流處理過程子類來(lái)控制不同的工作流類型,例如,另一種像并行切割模式那樣有著變化的執(zhí)行路徑的工作流。對(duì)于簡(jiǎn)單工作流來(lái)說,因?yàn)榛顒?dòng)的順序是預(yù)先決定了的,所以SequenceProcessor是好的選擇。盡管沒有被包括進(jìn)來(lái),對(duì)于使用基于spring的簡(jiǎn)單工作流的實(shí)現(xiàn)來(lái)說,排他選擇模式是另一個(gè)好的選擇。當(dāng)使用排他選擇模式時(shí),在每個(gè)活動(dòng)執(zhí)行之后,Processor具體類就會(huì)訊問ProcessorContext,接下來(lái)將要執(zhí)行哪一個(gè)活動(dòng)。
注:有關(guān)并行切割,排他選擇和其他工作流模式的更多信息,請(qǐng)參看W.M.P. van der Aalst等人寫的《工作流模式》一書。
啟動(dòng)工作流
考慮到工作流過程常常需要異步執(zhí)行的特點(diǎn),使用分離的執(zhí)行線程來(lái)啟動(dòng)工作流就變得有意義了。對(duì)于工作流的異步啟動(dòng)而言,有好幾個(gè)選項(xiàng);我們主要集中在其中的兩個(gè):積極地檢測(cè)(actively polling)一個(gè)隊(duì)列來(lái)啟動(dòng)工作流,或者使用通過ESB(enterprise service bus, 企業(yè)服務(wù)總線)的事件驅(qū)動(dòng)方式來(lái)啟動(dòng)工作流,而Mule就是ESB的一個(gè)開源項(xiàng)目(關(guān)于Mule的更多信息,請(qǐng)參加"Event-Driven Services in SOA"(JavaWorld, 2005年1月)。
圖3和圖4描繪了兩種啟動(dòng)策略。圖3中,積極檢測(cè)在工作流中第一個(gè)活動(dòng)經(jīng)常檢查資源的情形下發(fā)生,比如數(shù)據(jù)源或POP3郵件帳戶。如果圖3中的積極檢測(cè)發(fā)現(xiàn)有任務(wù)等待處理,那么啟動(dòng)就會(huì)開始。
圖 3. 通過積極檢測(cè)來(lái)啟動(dòng)工作流
另一方面,圖4表示了使用JMS(JAVA消息服務(wù))的J2EE應(yīng)用程序把事件放到隊(duì)列上的情形。一個(gè)通過ESB配置的事件監(jiān)聽器收到圖4中的事件,并且開始工作流,這樣,啟動(dòng)工作流過程。
圖 4. 通過ESB事件來(lái)啟動(dòng)工作流
http://searchwebservices.techtarget.com.cn/tips/110/2127110.shtml
使用所提供樣例的代碼,讓我們更詳細(xì)的看看主動(dòng)選擇啟動(dòng)方式與事件驅(qū)動(dòng)的啟動(dòng)方式。
積極檢測(cè)
積極檢測(cè)是一種花費(fèi)較少的啟動(dòng)工作流過程的方案。SequenceProcessor足夠靈活,以使得能夠通過平滑的選擇工作來(lái)進(jìn)行啟動(dòng)過程。盡管并不令人滿意,在沒有時(shí)間進(jìn)行事件驅(qū)動(dòng)子系統(tǒng)的配置和部署的許多情景中,積極檢測(cè)是明智的選擇。
使用Spring的ScheduledTimerTask,檢測(cè)模式就能夠容易地裝配。缺點(diǎn)就是必須創(chuàng)建額外的活動(dòng)來(lái)進(jìn)行檢測(cè)。這個(gè)檢測(cè)活動(dòng)必須被設(shè)計(jì)來(lái)訊問某些實(shí)體,如數(shù)據(jù)庫(kù)表,pop郵件帳戶,或者Web服務(wù),然后決定新的工作是否等待參與到工作流中。
在所提供的例子中,PollingTestCase類實(shí)例化一個(gè)基于檢測(cè)的工作流過程。使用一個(gè)有著積極檢測(cè)處理過程與事件驅(qū)動(dòng)的啟動(dòng)過程的不同之處在于,spring支持doActivities()方法的無(wú)參數(shù)版本。相反地,在事件驅(qū)動(dòng)的啟動(dòng)中,啟動(dòng)處理過程的實(shí)體通過doActivities(Object seedData)方法提供了種子數(shù)據(jù)來(lái)啟動(dòng)工作流。檢測(cè)方法的另一個(gè)缺點(diǎn)是:資源不一定能夠被重復(fù)地使用。依賴于應(yīng)用程序環(huán)境,這種資源的消耗是不可接受的。
下面代碼例子演示了使用積極檢測(cè)來(lái)控制工作流啟動(dòng)的一個(gè)活動(dòng):
public class PollForWork implements Activity
{
?? public ProcessContext execute(ProcessContext context) throws Exception {
????? //First check if work needs to be done
????? boolean workIsReady = lookIntoDatabaseForWork();
????? if (workIsReady) {
???????? //The Polling Action must also load any seed data
???????? ((MyContext) context).setSeedData(createSeedData());
????? } else {
???????? //Nothing to do, terminate the workflow process for this iteration
???????? ((MyContext) context).setStopEntireProcess(true);
????? }
????? return context;
?? }
}
此外,包含在例子代碼的單元測(cè)試中的PollRates類提供了一個(gè)主動(dòng)選舉啟動(dòng)的可以運(yùn)行的例子。PollRates模擬了對(duì)于航線費(fèi)率下降的重復(fù)檢查。
通過ESB的事件驅(qū)動(dòng)啟動(dòng)工作流
理想地,一個(gè)包含了適當(dāng)?shù)姆N子數(shù)據(jù)的線程能夠異步地啟動(dòng)工作流。這種情況的一個(gè)例子是收到從JAVA消息服務(wù)隊(duì)列的消息。一個(gè)監(jiān)聽JMS隊(duì)列或者主題的客戶會(huì)收到通知,這個(gè)通知告知處理應(yīng)該在onMessage()方法中開始工作流。然后,通過使用Spring和doActivities(Object seedData)方法就能夠獲得工作流處理器Bean。
使用ESB,實(shí)際用于發(fā)送啟動(dòng)事件的機(jī)制能夠恰當(dāng)?shù)貜墓ぷ髁魈幚砥髦蟹蛛x出來(lái)。開源項(xiàng)目Mule ESB有緊湊地和Spring相集成的好處。任意傳送機(jī)制,比如JMS,JVM,或者POP3郵箱都能夠發(fā)起事件的傳播。
工作流的連續(xù)運(yùn)行
工作流引擎后臺(tái)進(jìn)程應(yīng)該能夠沒有干擾地連續(xù)運(yùn)行。對(duì)于正在運(yùn)行的基于spring的工作流單一進(jìn)程來(lái)說好,有幾個(gè)選項(xiàng)。一個(gè)有著main()方法的簡(jiǎn)單Java類就足夠演示與這篇文章伴隨著的單元測(cè)試中的例子了。一個(gè)更加可靠的用于部署的機(jī)制是嵌入工作流到某種形式的J2EE組件中。Spring很好地支持和J2EE兼容的web應(yīng)用程序歸檔或者war文件的集成。基于Java管理附件(JMX)服務(wù)歸檔和JBoss應(yīng)用服務(wù)器(更多信息,參見JBoss homepage)支持的sar文件是更加合適的可部署組件,這種更合適的可部署組件也能夠被用來(lái)將部署歸檔。在JBoss 4.0中,sar文件已經(jīng)被大家所知道的deployer的格式所取代了。
例子代碼
打包成zip格式的例程代碼最好是用Apache Maven來(lái)使用它們。你能夠在主源代碼目錄src/java找到API。src/java目錄中有三個(gè)單元測(cè)試,包括:SimpleSequenceTestCase,RateDropTestCase和PoolingTestCase。要運(yùn)行所有這些測(cè)試,在命令行shell中鍵入maven test,然后在編譯和運(yùn)行之前,Maven將會(huì)下載所有必需的jar文件。實(shí)際的XSL轉(zhuǎn)換將會(huì)發(fā)生在兩個(gè)測(cè)試中,它們的結(jié)果被管道輸出到控制臺(tái)。鍵入maven test:ui來(lái)拉出圖形化的測(cè)試運(yùn)行器,然后選擇你想要運(yùn)行的測(cè)試,并且觀察控制臺(tái)的結(jié)果。
結(jié)論
在這篇文章中你已經(jīng)通過設(shè)計(jì)模式看到了工作流過程種類,在這些模式中,我們主要集中介紹了順序模式。通過使用接口,我們來(lái)對(duì)基本工作流組件建模。通過裝配多個(gè)接口實(shí)現(xiàn)到Spring,實(shí)現(xiàn)一個(gè)順序工作流。最后還討論了啟動(dòng)和部署工作流的不同選項(xiàng)。
這里所提出的簡(jiǎn)單工作流技術(shù)肯定不是最終的和革命性的。但是,使用Spring來(lái)實(shí)現(xiàn)像工作流這樣的通用任務(wù)是一個(gè)通過使用IoC容器而獲得的效率的好的示例。由于減少了粘合性代碼的需要,Spring在保持面向?qū)ο蟮募s束同時(shí),減少面向?qū)ο蟛僮髀闊┑某潭取?/u>
http://macrochen.blogdriver.com/macrochen/1088243.html
什么是工作流引擎(Workflow Engine )- -
所謂工作流引擎是指workflow作為應(yīng)用系統(tǒng)的一部分,并為之提供對(duì)各應(yīng)用系統(tǒng)有決定作用的根據(jù)角色、分工和條件的不同決定信息傳遞路由、內(nèi)容等級(jí)等核心解決方案。例如開發(fā)一個(gè)系統(tǒng)最關(guān)鍵的部分不是系統(tǒng)的界面,也不是和數(shù)據(jù)庫(kù)之間的信息交換,而是如何根據(jù)業(yè)務(wù)邏輯開發(fā)出符合實(shí)際需要的程序邏輯并確保其穩(wěn)定性、易維護(hù)性(模塊化和結(jié)構(gòu)化)和彈性(容易根據(jù)實(shí)際業(yè)務(wù)邏輯的變化作出程序上的變動(dòng),例如決策權(quán)的改變、組織結(jié)構(gòu)的變動(dòng)和由于業(yè)務(wù)方向的變化產(chǎn)生的全新業(yè)務(wù)邏輯等等)。 Workflow 引擎解決的就是這個(gè)問題:如果應(yīng)用程序缺乏強(qiáng)大的邏輯層,勢(shì)必變得容易出錯(cuò)(信息的路由錯(cuò)誤、死循環(huán)等等)。
就好比一輛汽車,外表做得再漂亮,如果發(fā)動(dòng)機(jī)有問題就只是一個(gè)擺設(shè)。應(yīng)用系統(tǒng)的彈性就好比引擎轉(zhuǎn)速方面的性能,加速到100 公里需要1 個(gè)小時(shí)(業(yè)務(wù)流程發(fā)生變動(dòng)需要進(jìn)行半年的程序修改)還能叫好車嗎?引擎動(dòng)不動(dòng)就熄火(程序因?yàn)檫壿嫷膯栴}陷入死循環(huán))的車還敢開嗎?
工作流解決方案與傳統(tǒng)管理軟件的關(guān)系傳統(tǒng)的管理軟件注重解決企業(yè)應(yīng)用層現(xiàn)存的問題(例如提高企業(yè)的資源配置率或提高單一員工的生產(chǎn)效率)。例如:EXCEL 可以提高員工畫表格的效率、財(cái)務(wù)軟件可以規(guī)范財(cái)務(wù)人員的工作并提高帳目查詢的效率、CRM 可以規(guī)范客戶管理從而使客戶資源掌握在公司手中而不是被一部分業(yè)務(wù)人員把持并提高客戶響應(yīng)時(shí)間、ERP 解決的是如何配置企業(yè)資源:使企業(yè)的人力資源、財(cái)力資源和物資資源能夠根據(jù)業(yè)務(wù)的需求實(shí)現(xiàn)最大化配置。 workflow 關(guān)注的是如何縮短流程閑置時(shí)間,從而提高企業(yè)的業(yè)務(wù)處理能力并使企業(yè)能夠關(guān)注于真正對(duì)企業(yè)有意義的增值業(yè)務(wù)上。從建立企業(yè)神經(jīng)系統(tǒng)的角度也許更能理解兩者的區(qū)別。傳統(tǒng)軟件不能解決工作流的問題,例如ERP 關(guān)注的是企業(yè)的資源配置,但不可能解決資源傳輸過程中的損耗和降低傳輸(流程)的成本;同樣workflow也不能完全解決傳統(tǒng)管理軟件所能解決的問題,例如對(duì)生產(chǎn)管理的MRP 系統(tǒng)所能解決的生產(chǎn)過程控制通過workflow很難實(shí)現(xiàn)。但一個(gè)好的傳統(tǒng)軟件如果希望能自動(dòng)化地在整個(gè)企業(yè)中應(yīng)用起來(lái),必須有一個(gè)強(qiáng)大的邏輯層,用以解決信息傳遞的邏輯判斷和自動(dòng)流轉(zhuǎn),這個(gè)時(shí)候就需要workflow的平臺(tái)。所以說: 1.workflow 和傳統(tǒng)管理軟件不是同一種軟件,不具可比性; 2.workflow 對(duì)于已經(jīng)有傳統(tǒng)管理軟件的企業(yè)的作用非常明顯,可以籍此平臺(tái)整合企業(yè)的各種應(yīng)用系統(tǒng),使之成為一個(gè)完整的企業(yè)級(jí)應(yīng)用,也就是通常所說的EAI. 3. 具備workflow功能的管理軟件(workflow與傳統(tǒng)管理軟件的結(jié)合)對(duì)于傳統(tǒng)管理軟件有絕對(duì)的優(yōu)勢(shì);4.workflow可以根據(jù)企業(yè)的需要開發(fā)解決信息傳遞問題的流程以及幫助企業(yè)開發(fā)與現(xiàn)有應(yīng)用系統(tǒng)的接口
工作流自動(dòng)化并不復(fù)雜因?yàn)橄率鰩讉€(gè)原因,工作流自動(dòng)化業(yè)界有" 適合處理復(fù)雜業(yè)務(wù)流程" 的名聲。
1.常規(guī)工作流自動(dòng)化軟件包及其部署相當(dāng)昂貴。通常,伴隨產(chǎn)品的是長(zhǎng)時(shí)期的咨詢關(guān)系。所以為了非常簡(jiǎn)單的業(yè)務(wù)流程購(gòu)買和部署軟件是被不被采納的。這些軟件通常只被用于復(fù)雜、關(guān)鍵和控制成本相對(duì)較高而工作流自動(dòng)化帶來(lái)的效益明顯的量產(chǎn)型工作流應(yīng)用。因此經(jīng)銷商和用戶都會(huì)不自覺地關(guān)注于將復(fù)雜的業(yè)務(wù)問題自動(dòng)化。 2. 處于類似原因,工作流研究人士首先會(huì)關(guān)注解決了哪些復(fù)雜的業(yè)務(wù)流程問題。
而對(duì)于大多數(shù)案例而言,為解決簡(jiǎn)單工作流程問題部署自動(dòng)化軟件的成本顯然是不經(jīng)濟(jì)的。這里遵循一條簡(jiǎn)單的道理:走之前必須先會(huì)爬,跑之前必須先會(huì)走。 3. 最后一條原因,也是"IT 業(yè)的尷尬".總經(jīng)理對(duì)IT部門經(jīng)理工作衡量的標(biāo)準(zhǔn)就是:能夠解決復(fù)雜問題的能力。自然,IT經(jīng)理就會(huì)不遺余力地解決那些復(fù)雜的問題,他們的方案通常也就復(fù)雜而且昂貴。
所有這些目前都在改變。針對(duì)桌面電腦的應(yīng)用方案快速發(fā)展以及工作流解決方案的發(fā)展使解決日常工作流程問題成為可能。費(fèi)用不再昂貴,部署更為簡(jiǎn)便。事實(shí)上,企業(yè)越來(lái)越意識(shí)到工作流的重要性,同時(shí)在部署復(fù)雜關(guān)鍵的流程自動(dòng)化之前,愿意從一些簡(jiǎn)單的流程入手積累經(jīng)驗(yàn)。
工作流會(huì)成為操作系統(tǒng)的一部分嗎?
有人認(rèn)為工作流會(huì)成為操作系統(tǒng)平臺(tái)(例如WINDOWS 平臺(tái))的一部分。我們的觀點(diǎn)是,基于下述幾個(gè)原因,在可預(yù)見的未來(lái),工作流不會(huì)成為操作系統(tǒng)的一部分: 1. 擴(kuò)展表格、文字處理程序和數(shù)據(jù)庫(kù)存在了20多年,成了家喻戶曉的名詞。這些技術(shù)被廣泛理解和應(yīng)用,也相應(yīng)形成了各自的標(biāo)準(zhǔn)和相關(guān)術(shù)語(yǔ)。然而因?yàn)楹芏嘣颍钡浇裉爝@些技術(shù)也沒有成為操作系統(tǒng)的一部分。最重要的原因之一是用戶需要差異和選擇的自由。相比較而言,工作流自動(dòng)化軟件是較新的技術(shù),也更有差異性、不易被廣泛理解并且比這些技術(shù)更為先進(jìn)。因?yàn)楣ぷ髁鞒痰牟町愋院蛷?fù)雜性,工作流自動(dòng)化的用戶需要更多的選擇空間。
2.財(cái)務(wù)軟件包從電腦發(fā)明后就迅速普及了。這是實(shí)施、術(shù)語(yǔ)和規(guī)則被普遍接受的另一個(gè)領(lǐng)域。然而至今也沒有哪種操作系統(tǒng)吹噓集成了多少財(cái)務(wù)軟件的功能。而工作流自動(dòng)化軟件比財(cái)務(wù)軟件更為復(fù)雜和有差異性。 3. 操作系統(tǒng)提供商,例如微軟和Sun ,不會(huì)為了使其系統(tǒng)具備工作流自動(dòng)化的功能而大量改變他們現(xiàn)有的系統(tǒng)。他們有什么必要為工作流自動(dòng)化軟件投入開發(fā)和支持的成本呢? 4. 操作系統(tǒng)是為常規(guī)條件設(shè)計(jì)并使之最優(yōu)化。正因如此,目前操作系統(tǒng)的開發(fā)成本幾乎都要上億美元。業(yè)務(wù)流程十分復(fù)雜并充滿了例外情況,如在操作系統(tǒng)中內(nèi)嵌工作流自動(dòng)化程序會(huì)極大地增加開發(fā)成本和難度。因此,即便操作系統(tǒng)提供商決定做工作流軟件,也會(huì)是巨額投入開發(fā)一套新的操作系統(tǒng),而不是將工作流嵌入。
事實(shí)上,今天的很多優(yōu)秀的工作流解決方案集成了短信息、頁(yè)面服務(wù)、目標(biāo)管理、文件管理和其他一些操作系統(tǒng)才提供的服務(wù)。
工作流自動(dòng)化的主要成分工作流自動(dòng)化如今成了管理的一句時(shí)髦話。市面上也有很多號(hào)稱能激活工作流的自動(dòng)化產(chǎn)品。只要他們的應(yīng)用程序支持基本的E-mail功能,賣主就會(huì)隨意地把" 激活工作流" 作為標(biāo)簽貼在產(chǎn)品上。然而,這類產(chǎn)品和真正工作流自動(dòng)化軟件之間的差別就如同寫字版和Word之間的差別。我們相信,應(yīng)用程序只有具備了下列主要特征,才能稱其為工作流自動(dòng)化解決方案:
能夠畫出工作流程圖,當(dāng)然以圖形化界面設(shè)計(jì)的為佳;能為每個(gè)步驟設(shè)計(jì)電子表格;能將外部應(yīng)用程序結(jié)合為工作流自動(dòng)化的一部分;能與電子表格及企業(yè)數(shù)據(jù)庫(kù)相連接;能設(shè)計(jì)基于復(fù)雜業(yè)務(wù)規(guī)則的條件型路由的工作流程圖,最好無(wú)須編程;能根據(jù)功能、用戶名稱或上下級(jí)關(guān)系按規(guī)則傳遞信息;能夠監(jiān)控工作流執(zhí)行狀況;能夠?qū)ぷ髁鬟M(jìn)行調(diào)節(jié);能夠模擬并測(cè)試工作流的行為;工作流的應(yīng)用必須支持多用戶并具高度可靠性;工作流的應(yīng)用必須支持內(nèi)部網(wǎng)或英特網(wǎng)及跨多種平臺(tái)。
網(wǎng)友討論工作流應(yīng)該是一個(gè)中間件而不應(yīng)該是一個(gè)完整的系統(tǒng)。工作流應(yīng)該整合到其他系統(tǒng)中而不是單獨(dú)使用。
工作流要完成的核心功能有流程設(shè)計(jì),流程執(zhí)行,流程和線程的調(diào)度,任務(wù)的分派與通知,集成已有信息系統(tǒng)(很多人忘了)。
工作流應(yīng)該提供對(duì)組織機(jī)構(gòu),用戶,權(quán)限管理,流程,任務(wù)的管理能力,但是對(duì)這些管理能力最基本實(shí)現(xiàn)方式是提供API ,而不是一個(gè)管理系統(tǒng),即使把這些管理作為一個(gè)管理系統(tǒng)來(lái)實(shí)現(xiàn)(A ),也主要是用于演示,因?yàn)楫?dāng)工作流用于其它系統(tǒng)(B ),因?yàn)锽 需要一個(gè)統(tǒng)一的管理界面,所以通常不會(huì)直接使用A.而表單設(shè)計(jì),報(bào)表之類根本就是外圍功能,是二次開發(fā)商的任務(wù)。
我基本贊同wangtaoyy 的說法,再補(bǔ)充一點(diǎn)。我覺得工作流與其說是中間件,還不如說是一個(gè)應(yīng)用整合和集成的框架。類似在j2ee規(guī)范下各產(chǎn)商開發(fā)的應(yīng)用服務(wù)器,工作流也應(yīng)當(dāng)是在wfmc標(biāo)準(zhǔn)下開發(fā)出來(lái)的" 容器" ,只要是滿足了標(biāo)準(zhǔn)的應(yīng)用程序或組件都能夠在這個(gè)" 容器" 中按照預(yù)定的規(guī)則被調(diào)度和執(zhí)行。我認(rèn)為理想情況下工作流系統(tǒng)不應(yīng)該提供API 作二次開發(fā),工作流的內(nèi)部對(duì)基于工作流的應(yīng)用程序應(yīng)當(dāng)是完全不透明的,工作流應(yīng)當(dāng)提供給開發(fā)者的是一個(gè)類似于J2EE那樣的標(biāo)準(zhǔn),一套編程模型和接口模型。開發(fā)者在這個(gè)模型下去實(shí)現(xiàn)那些接口,開發(fā)出應(yīng)用組件,再利用工作流提供的管理器進(jìn)行" 注冊(cè)".總而言之,對(duì)開發(fā)者而言,工作流是黑箱,他需要做的事情是開發(fā)標(biāo)準(zhǔn)組件,在工作流提供的UI管理工具中配置業(yè)務(wù)流程,包括業(yè)務(wù)過程、資源、權(quán)限、時(shí)間、規(guī)則等等。
1. j2ee 應(yīng)用服務(wù)器也是中間件的一種。
2. 工作流要做成j2ee哪樣的標(biāo)準(zhǔn)還是比較困難的, j2ee 重點(diǎn)在于提供開發(fā)全新系統(tǒng)的能力,所以可以制定比較好的容器- 組件標(biāo)準(zhǔn),而工作流的重點(diǎn)是整合已經(jīng)存在的系統(tǒng),要在這些各式各樣的老系統(tǒng)上強(qiáng)加標(biāo)準(zhǔn)是不現(xiàn)實(shí)的。
3.工作流應(yīng)該提供api ,因?yàn)槠渌到y(tǒng)中的一些事件可能會(huì)啟動(dòng)一個(gè)流程,或者觸發(fā)其他與流程相關(guān)的東西
工作流分為兩種類型,一種是嵌入式的,另一種是非嵌入式的。這在WFMC的文檔中已經(jīng)有所介紹,大家可以找找看一下。按照工作流管理聯(lián)盟的文檔,大家說的都沒有什么錯(cuò)誤,只是側(cè)重點(diǎn)不同。wangtaoyy 的觀點(diǎn)傾向于前者,而coffeewoo 的觀點(diǎn)傾向于后者。
我的看法并不是趨向于嵌入式工作流。我理解的工作流提供的api 并不是一般軟件包的API ,而是一種服務(wù)方式的API ,類似于操作系統(tǒng)中的系統(tǒng)調(diào)用。
我們?cè)谲浖写罅渴褂昧瞬僮飨到y(tǒng)提供的系統(tǒng)調(diào)用API ,但是操作系統(tǒng)并不是嵌入到我們軟件系統(tǒng)中的。我認(rèn)為工作流系統(tǒng)與操作系統(tǒng)有很強(qiáng)的可比性,只是工作流層次更高。比如流程設(shè)計(jì)相當(dāng)于編程,模型相當(dāng)于程序,流程實(shí)例相當(dāng)于進(jìn)程,流程分支相當(dāng)于線程,操作系統(tǒng)要對(duì)進(jìn)程和線程進(jìn)行調(diào)度,工作流引擎要對(duì)流程實(shí)例和分支進(jìn)行調(diào)度,操作系統(tǒng)和工作流系統(tǒng)都應(yīng)該對(duì)內(nèi)存進(jìn)行管理避免耗盡系統(tǒng)內(nèi)存,操作系統(tǒng)提供系統(tǒng)調(diào)用API 而工作流引擎提供工作流API.何其相似。
從功能的角度看:工作流系統(tǒng)的本職工作就是管理和控制業(yè)務(wù)流程,例如:流程實(shí)例的啟動(dòng)、停止;環(huán)節(jié)實(shí)例的啟動(dòng)、結(jié)束;任務(wù)的分配等等。從工作流系統(tǒng)的組成看:工作流系統(tǒng)應(yīng)該包括流程引擎、流程定義工具、運(yùn)行管理工具、api 系統(tǒng)。工作流系統(tǒng)應(yīng)該該不包括表單定義、組織機(jī)構(gòu)定義及其管理、權(quán)限管理、數(shù)據(jù)流管理等等。
工作流系統(tǒng)雖然不包括上述功能,但是工作流系統(tǒng)一定會(huì)和上述功能發(fā)生交互關(guān)系,所以好的工作流產(chǎn)品并不是一個(gè)包辦上述功能的產(chǎn)品,而是一個(gè)設(shè)計(jì)良好的能夠和上述功能交互的系統(tǒng)。從和其他系統(tǒng)的關(guān)系看待工作流:如果站在基礎(chǔ)業(yè)務(wù)平臺(tái)的角度,那么,工作流系統(tǒng)、組織機(jī)構(gòu)管理系統(tǒng)、表單自定義系統(tǒng)、權(quán)限管理系統(tǒng)、數(shù)據(jù)流管理系統(tǒng)、報(bào)表系統(tǒng)都是這個(gè)基礎(chǔ)業(yè)務(wù)平臺(tái)的服務(wù)。業(yè)務(wù)功能系統(tǒng)在運(yùn)行的過程中會(huì)調(diào)用這些服務(wù),這些服務(wù)之間本身也可能互相調(diào)用。例如:工作流服務(wù)和組織機(jī)構(gòu)管理服務(wù)之間的關(guān)系就非常密切,盡管如此,如果認(rèn)為工作流系統(tǒng)一定包含組織機(jī)構(gòu)管理系統(tǒng)應(yīng)該是不正確的。在oa系統(tǒng)中,表單自定義好像比較重要,而且流程常常需要引用表單上的數(shù)據(jù),但是表單自定義絕對(duì)不是工作流系統(tǒng)的組成部分。流程在運(yùn)行的過程中可能跨多個(gè)數(shù)據(jù)庫(kù)系統(tǒng),任務(wù)在流轉(zhuǎn)的過程中需要“攜帶”大量的業(yè)務(wù)數(shù)據(jù),但是這些也不是工作流要做的事情,完成這些工作的系統(tǒng)我稱之為“數(shù)據(jù)流管理系統(tǒng)”。總之:從功能的角度,所有的功能都是必要的,但是從技術(shù)的角度,這些功能不可以做到一個(gè)“鐵板一塊”的所謂的“工作流”里面去。從技術(shù)發(fā)展的趨勢(shì)看:工作流系統(tǒng)很可能發(fā)展成為一個(gè)類似關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)的專職的系統(tǒng)。我那個(gè)工作流東東還在改進(jìn)中,希望作出一個(gè)設(shè)計(jì)合理的(決對(duì)不是強(qiáng)行coding出來(lái)的),工程實(shí)用的東西出來(lái)