![spring技術(shù)工作流_第1頁](http://file4.renrendoc.com/view/baf7939f1b5df4aeb80b8266b4383a46/baf7939f1b5df4aeb80b8266b4383a461.gif)
![spring技術(shù)工作流_第2頁](http://file4.renrendoc.com/view/baf7939f1b5df4aeb80b8266b4383a46/baf7939f1b5df4aeb80b8266b4383a462.gif)
![spring技術(shù)工作流_第3頁](http://file4.renrendoc.com/view/baf7939f1b5df4aeb80b8266b4383a46/baf7939f1b5df4aeb80b8266b4383a463.gif)
![spring技術(shù)工作流_第4頁](http://file4.renrendoc.com/view/baf7939f1b5df4aeb80b8266b4383a46/baf7939f1b5df4aeb80b8266b4383a464.gif)
![spring技術(shù)工作流_第5頁](http://file4.renrendoc.com/view/baf7939f1b5df4aeb80b8266b4383a46/baf7939f1b5df4aeb80b8266b4383a465.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、基于Spring創(chuàng)建工作流引擎Spring 框架()是一個(gè)基于 POJO 的輕量級 J2EE 應(yīng)用框架,它支持一種比較新的編程方法:控制反轉(zhuǎn)(Inversion of Contro)。本文介紹 如何把后端處理任務(wù)組織成易于使用、基于Spring的工作流。許多J2EE應(yīng)用程序要求在與主系統(tǒng)分離的上下文中執(zhí)行處理過程。許多情況下,這些 后端過程執(zhí)行幾個(gè)任務(wù),有些任務(wù)依賴于前一個(gè)任務(wù)的狀態(tài)。由于需要處理任務(wù)之間相互依 賴的關(guān)系,使用一套過程式的調(diào)用方法來實(shí)現(xiàn)通常無法滿足要求。開發(fā)人員利用Spring, 就很容易把后端過程劃分成一個(gè)個(gè)活動(dòng)組成的集合。Spring容器可以結(jié)合這些活動(dòng),組成 簡單工作流。
2、本文把簡單工作流定義為:不需要用戶交互,按預(yù)定順序執(zhí)行的任何一組活動(dòng)。然而, 我們并不建議用這種方法取代現(xiàn)有的工作流框架。如果有些場景需要比較高級的用戶交互, 譬如基于用戶輸入的分叉、結(jié)合或者轉(zhuǎn)換,使用獨(dú)立的開源或者商用工作流引擎比較有效。 有一個(gè)開源項(xiàng)目已經(jīng)成功地將比較復(fù)雜的工作流設(shè)計(jì)與Spring實(shí)現(xiàn)了集成(參閱: /display/WF/2.3+Spring+什amework)。如果手頭的工作流任務(wù)非常簡單,那么明智之舉是使用簡單工作流這一方法,而不是功 能完備的獨(dú)立工作流框架。如果已經(jīng)在使用Spring,更是如此,因?yàn)榭梢员WC迅速實(shí)現(xiàn), 而不會帶來項(xiàng)目啟動(dòng)時(shí)間。另外,考慮到Spring
3、輕量級的控制反轉(zhuǎn)容器具有的特性,Spring 減少了資源開銷。簡單工作流工作流建模是早在20世紀(jì)70年代就有人研究的一個(gè)課題,許多開發(fā)人員試圖創(chuàng)建標(biāo)準(zhǔn) 化的工作流建模規(guī)范。W.H.M. van der Aalst與人合著的白皮書:工作流模式已成功 地確認(rèn)了一組設(shè)計(jì)模式,這些模式可以準(zhǔn)確地為最常見的的工作流場景建模。其中最基本的 工作流模式是順序(Sequence)模式。順序工作流模式符合簡單工作流的標(biāo)準(zhǔn),由按順序 執(zhí)行的一組活動(dòng)組成。統(tǒng)一建模語言(UML)活動(dòng)圖通常作為工作流建模的一種機(jī)制使用。圖1顯示了使用標(biāo) 準(zhǔn)的UML活動(dòng)圖來建模的基本的順序工作流過程。順序工作流是J2EE應(yīng)用程序中很普遍
4、的一種標(biāo)準(zhǔn)工作流模式。J2EE應(yīng)用程序通常需要按順序排列的事件在背景線程中進(jìn)行,或者異步進(jìn)行。圖2的活動(dòng)圖描述了一個(gè)簡單工作 流,用于通知感興趣的旅客:他們常去的目的地的機(jī)票價(jià)格已下調(diào)。圖1中的航線工作流負(fù)責(zé)創(chuàng)建及發(fā)送動(dòng)態(tài)的電子郵件通知。工作流過程中的每一步就代 表一個(gè)活動(dòng)。工作流啟動(dòng)之前,一些外部事件必須發(fā)生。在這個(gè)例子中,這個(gè)外部事件就是 航線費(fèi)率下調(diào)。我們詳細(xì)看一下航線工作流的業(yè)務(wù)邏輯。如果第一個(gè)活動(dòng)找不到對費(fèi)率下調(diào)通知有興趣 的用戶,整個(gè)工作流就被取消。如果發(fā)現(xiàn)了有興趣的用戶,就會完成剩余的幾個(gè)活動(dòng)。隨后, 可擴(kuò)展樣式語言(XSL)轉(zhuǎn)換會生成消息內(nèi)容,之后記錄審計(jì)信息。最后,試圖通過S
5、MTP 服務(wù)器發(fā)送該消息。如果提交完成又沒有錯(cuò)誤,就記錄成功的信息,結(jié)束整個(gè)過程。但是, 如果在與SMTP服務(wù)器通信時(shí)發(fā)生了錯(cuò)誤,一個(gè)特別的錯(cuò)誤處理例程就會接管工作。這部 分錯(cuò)誤處理代碼會試圖重新發(fā)送消息。就這個(gè)航線例子而言,一個(gè)明顯的問題是:如何有效地把順序過程分解成一個(gè)個(gè)活動(dòng)?Spring可以巧妙地處理這個(gè)問題。我們不妨先討論一下Spring這種反轉(zhuǎn)控制框架。Spring把控制對象的依賴關(guān)系這個(gè)責(zé)任交給了 Spring容器去處理,這樣我們就不必為 之操心。這種責(zé)任的轉(zhuǎn)移就叫控制反轉(zhuǎn)(IoC)或者依賴注射(Dependency Injection)。 Martin Fowler所著的控制反轉(zhuǎn)
6、容器和依賴注射模式( HYPERLINK /articles/injection.html)%e6%af%94%e8%be%83%e6%b7%b1%e5%85%a5%e5%9c%b0%e8%ae%a8%e8%ae%ba%e4%ba%86%e6%8e%a7%e5%88%b6%e5%8f%8d%e8%bd%ac%e5%92%8c%e4%be%9d /articles/injection.html)比較深入地討論了控制反轉(zhuǎn)和依 賴注射。由于Spring可以管理對象之間的依賴關(guān)系,因而不需要粘合代碼(glue code), 即完全是為了讓類與類能相互協(xié)作而編寫的代碼。作為Spring bean的工作流
7、組件在我們深入討論之前,有必要先來介紹一下Spring的幾個(gè)主要概念。從BeanFactory 接口繼承而來的ApplicationContext接口充當(dāng)Spring里面的實(shí)際控制實(shí)體或者容器。ApplicationContext負(fù)責(zé)為一組名為Spring bean的bean創(chuàng)建實(shí)例、進(jìn)行配置及生命 周期管理。只要對基于XML的配置文件中的Spring bean進(jìn)行裝配,就可以對ApplicationContext進(jìn)行配置。這個(gè)配置文件規(guī)定了 Spring bean互相協(xié)作的特性。因 而,用Spring的行語來講,與其他Spring beans交互的Spring bean就叫協(xié)作對象(coll
8、aborator)。默認(rèn)情況下,Spring bean 在 ApplicationContext 中作為單例(singleton)而存在,但是單例屬性可以設(shè)置成false,實(shí)際上改變了 Spring調(diào)用原型模 式的行為?;氐轿覀兦懊婧骄€費(fèi)率下調(diào)的那個(gè)例子,SMTP發(fā)送例程的抽象被裝配成了工作流過程 例子中的最后一個(gè)活動(dòng)。由于是第5個(gè)活動(dòng),這個(gè)bean被命名為activity5。要發(fā)送消息, activity5就需要委托協(xié)作對象和錯(cuò)誤處理例程。property name=errorHandlerref bean = mailErrorHandler/property/bean把工作流組件實(shí)施成S
9、pring bean帶來了兩個(gè)所需的結(jié)果:一是容易進(jìn)行單元測試;二 是大大提高了重用性。考慮到控制反轉(zhuǎn)容器具有的特性,單元測試的高效優(yōu)點(diǎn)一目了然。使 用像Spring這樣的控制反轉(zhuǎn)容器,協(xié)作對象之間的依賴關(guān)系在測試期間很容易用假的替代 關(guān)系來置換。在上述例子中,很容易從獨(dú)立的測試ApplicationContext中檢索到像 activity5這樣的Spring bean。如果用activity5代替假的SMTP委托協(xié)作對象,就有可 能對activity5單獨(dú)進(jìn)行單元測試。第二個(gè)結(jié)果:重用性可通過XSL轉(zhuǎn)換這樣的工作流活動(dòng)來實(shí)現(xiàn)XSL轉(zhuǎn)換被抽象成工作 流活動(dòng)后,現(xiàn)在就可以由處理XSL轉(zhuǎn)換的任何
10、工作流重復(fù)使用。裝配工作流在提供的API中,Spring控制一小組接口,這些接口的交互方式組成了工作流。關(guān)鍵 接口如下:Activity:封裝了工作流中每一步的業(yè)務(wù)邏輯。ProcessContext:類型ProcessContext的對象在工作流中的各活動(dòng)之間傳遞。實(shí)現(xiàn) 這個(gè)接口的對象負(fù)責(zé)在工作流從一個(gè)活動(dòng)轉(zhuǎn)換到另一個(gè)活動(dòng)過程中保持對象狀態(tài)。ErrorHandler:提供了處理錯(cuò)誤的回調(diào)方法。Processor:描述了為主工作流線程充當(dāng)執(zhí)行者的bean。以下有關(guān)Spring bean配置的代碼利用航線費(fèi)率例子描述了簡單工作流的過程。bean id = rateDropProcessor cla
11、ss=org.iocworkflow.SequenceProcessorproperty name=activitieslistref bean=activity1/ref bean=activity2/ref bean=activity3/ref bean=activity4/ref bean=activity5/list/propertyproperty name=defaultErrorHandlerref bean=defaultErrorHandler/propertyproperty name=processContextClassvalueorg.iocworkflow.test
12、.sequence.ratedrop.RateDropContext/propertySequenceProcessor類是為順序模式建模的一個(gè)具體子類。有5個(gè)活動(dòng)被連接到了工作流處理器(processor),它會按順序執(zhí)行這5個(gè)活動(dòng)。與大多數(shù)過程性后端過程相比,工作流解決方案確實(shí)與眾不同,它能夠非??煽康靥幚?錯(cuò)誤??梢詾槊總€(gè)活動(dòng)單獨(dú)裝配錯(cuò)誤處理例程。這種類型的例程在單個(gè)活動(dòng)層面提供了粒度 很細(xì)的錯(cuò)誤處理機(jī)制。如果沒有為某個(gè)活動(dòng)裝配任何錯(cuò)誤處理例程,那么為整個(gè)工作流處理 器定義的錯(cuò)誤處理例程就會處理問題。就這個(gè)例子而言,如果在工作流過程期間的任何時(shí)刻 出現(xiàn)了未得到處理的錯(cuò)誤,它就會向外傳播,
13、讓使用defaultErrorHandler屬性裝配而成 的 ErrorHandler bean 來處理。比較復(fù)雜的工作流框架為數(shù)據(jù)存儲區(qū)在工作流轉(zhuǎn)換期間賦予了持久性的狀態(tài)。在本文中, 我們只關(guān)注狀態(tài)轉(zhuǎn)換自動(dòng)進(jìn)行的簡單工作流。只有在實(shí)際工作流運(yùn)行期間才能從 ProcessContext處得到狀態(tài)信息。可以看到,ProcessContext接口只有兩個(gè)方法:public interface ProcessContext extends Serializable public boolean stopProcess();public void setSeedData(Object seedObje
14、ct);航線例子工作流所用的具體的ProcessContext類是RateDropContext類。 RateDropContext類封裝執(zhí)行航線費(fèi)率下調(diào)工作流所必需的數(shù)據(jù)。到現(xiàn)在為止,根據(jù)默認(rèn)ApplicationContext的行為,所有bean實(shí)例都已經(jīng)成了單例。 但是對于航線工作流的每次調(diào)用,我們都要?jiǎng)?chuàng)建RateDropContext類的新實(shí)例。為了滿 足這種需求,需要配置SequenceProcessor,采用完全符合標(biāo)準(zhǔn)的類名作為 processContextClass屬性。對于每次工作流執(zhí)行,SequenceProcessor都使用指定的 類名,從Spring檢索到Process
15、orContext類的新實(shí)例。這種機(jī)制要起到作用,非單例的 Spring bean 或者類型 org.iocworkflow.test.sequence.simple.SimpleContext 的原 型就必須位于ApplicationContext里面。為工作流播種我們已經(jīng)知道了如何使用Spring組建簡單工作流,現(xiàn)在著重介紹使用種子數(shù)據(jù)(seed data)來創(chuàng)建實(shí)例。想知道如何為工作流播種,不妨看一下實(shí)際的接口 Processor所采用 的方法:public interface Processor public boolean supports(Activity activity);pu
16、blic void doActivities();public void doActivities(Object seedData);public void setActivities(List activities);public void setDefaultErrorHandler(ErrorHandler defaultErrorHandler);大多數(shù)情況下,工作流過程需要一些初始的刺激才能啟動(dòng)。啟動(dòng)處理器有兩個(gè)方法: doActivities(ObjectseedData)方法,或者沒有變量的doActivities()。以下代碼片段是包含在示例代碼中為SequenceProces
17、sor實(shí)現(xiàn)的doActivities():public void doActivities(Object seedData) /由Spring注入檢索List activities = getActivities();檢索工作流ProcessContext的新實(shí)例ProcessContext context = createContext();if (seedData != null)context.setSeedData(seedData);按順序執(zhí)行每個(gè)活動(dòng)for (Iterator it = activities.iterator(); it.hasNext();) Activity a
18、ctivity = (Activity) it.next();try context = activity.execute(context); catch (Throwable th) 在活動(dòng)層面確定有沒有錯(cuò)誤處理例程ErrorHandler errorHandler = activity.getErrorHandler();if (errorHandler = null) getDefaultErrorHandler().handleError(context, th);break; else 使用默認(rèn)處理例程處理錯(cuò)誤errorHandler.handleError(context, th)
19、;確保過程可以繼續(xù)執(zhí)行if (processShouldStop(context, activity)break;在這個(gè)航線費(fèi)率下調(diào)的例子中,工作流過程的種子數(shù)據(jù)包括:航線信息和費(fèi)率下調(diào)信息。 利用容易測試的航線工作流例子,就很容易通過doActivities(Object seedData)方法 為單一工作流過程提供種子數(shù)據(jù),并啟動(dòng)它:BaseProcessor processor =(BaseProcessor)context.getBean(rateDropProcessor);processor.doActivities(createSeedData();rateDropProcess
20、or bean 是從 ApplicationContext 檢索而來的。 rateDropProcessor其實(shí)裝配成SequenceProcessor的實(shí)例,以處理順序執(zhí)行。createSeedData ()方法為負(fù)責(zé)封裝初始化航線工作流所需的所有種子數(shù)據(jù)的對象創(chuàng)建了 實(shí)例。處理器選項(xiàng)雖然SequenceProcessor是包括在源代碼里面的Processor的惟一具體子類,但Processor接口的許多實(shí)現(xiàn)是可以想象得到的??梢蚤_發(fā)工作流處理器的其他子類,以控 制不同類型的工作流,譬如說,有著不同執(zhí)行路徑如并行分叉(Parallel Splits)模式的其 他工作流。SequencePro
21、cessor之所以非常適用于簡單工作流,就是因?yàn)榛顒?dòng)順序已事先 確定。雖然本文并沒有介紹,但排他選擇(Exclusive Choice)模式是適用于使用Spring 的簡單工作流來實(shí)現(xiàn)的另一種模式。就排他選擇模式而言,每個(gè)活動(dòng)執(zhí)行完畢后,Processor 具體類會詢問ProcessorContext:接下來要執(zhí)行哪一個(gè)Activity。注意:想進(jìn)一步了解并行分叉、排他選擇及其他工作流模式,請參閱W.M.P. van der Aalst等人所著的工作流模式一書。啟動(dòng)工作流考慮到工作流過程常常需要異步執(zhí)行的特點(diǎn),有必要使用分離的執(zhí)行線程來啟動(dòng)工作流。 有幾種方法能夠以異步方式啟動(dòng)工作流。我們主要
22、介紹兩種:主動(dòng)輪詢隊(duì)列來啟動(dòng)工作流, 或者通過企業(yè)服務(wù)總線(ESB)如開源ESB: Mule的事件驅(qū)動(dòng)啟動(dòng)方法。圖3和圖4描繪了這兩種啟動(dòng)策略。圖3中,主動(dòng)輪詢出現(xiàn)在這種情況下:工作流中的 第一個(gè)活動(dòng)不斷檢查資源,譬如數(shù)據(jù)源或者POP3電子郵件賬戶。如果圖3中的輪詢活動(dòng) 發(fā)現(xiàn)有任務(wù)等待處理,就開始啟動(dòng)工作流。另一方面,圖4表示了使用Java消息服務(wù)(JMS)的J2EE應(yīng)用程序把事件放到隊(duì)列中的情形。通過ESB配置的事件偵聽器收到圖4中的事件后,為工作流播種,從而啟動(dòng)工 作流過程。主動(dòng)輪詢是啟動(dòng)工作流過程的一種比較簡單的解決方案。SequenceProcessor極其靈 活,可以讓輪詢啟動(dòng)順暢進(jìn)
23、行。盡管不是令人滿意,但在沒有時(shí)間配置及部署事件驅(qū)動(dòng)型子 系統(tǒng)的許多情況下,主動(dòng)輪詢顯然是合理的選擇。使用Spring的ScheduledTimerTask,就很容易實(shí)現(xiàn)輪詢方案。一個(gè)不足就是,必須 創(chuàng)建額外的Activity才能進(jìn)行輪詢。創(chuàng)建這個(gè)負(fù)責(zé)輪詢的Activity是為了查詢某個(gè)實(shí)體, 譬如數(shù)據(jù)庫表、pop郵件賬戶或者Web服務(wù),然后確定某個(gè)新的工作是否等待處理。在本文提供的例子中,PollingTest-Case類為基于輪詢的工作流處理器創(chuàng)建實(shí)例。主動(dòng) 輪詢啟動(dòng)不同于事件驅(qū)動(dòng)啟動(dòng)的地方在于,Spring偏愛使用沒有變量的doActivities() 方法。反過來,在事件驅(qū)動(dòng)啟動(dòng)中,啟
24、動(dòng)處理器的實(shí)體通過doActivities(Object seedData)方法提供了種子數(shù)據(jù)。主動(dòng)輪詢的另一個(gè)缺點(diǎn)是:資源被不必要地重復(fù)耗用。 這種資源耗用可能讓人無法接受,具體耗用多少取決于應(yīng)用程序環(huán)境。以下代碼例子演示了使用主動(dòng)輪詢來控制工作流啟動(dòng)的一個(gè)活動(dòng):public class PollForWork implements Activitypublic ProcessContext execute(ProcessContext context) throws Exception 先檢查是否有工作需要處理boolean workIsReady = lookIntoDatabaseForWork();if (workIsReady) 輪詢行動(dòng)還必須加載任何種子數(shù)據(jù)(MyContext) context).setSeedData(createSeedData(); else 沒有工作要處理,終止工作流過程(MyContext) context).setStopE
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024學(xué)年泰州市靖江八年級語文第一學(xué)期12月調(diào)研試卷附答案解析
- 2025年農(nóng)業(yè)物資供應(yīng)鏈優(yōu)化管理協(xié)議
- 2025年專業(yè)除鼠服務(wù)合同
- 2025年出租車經(jīng)營權(quán)承接策劃協(xié)議
- 2025年通信傳輸設(shè)備項(xiàng)目規(guī)劃申請報(bào)告模范
- 2025年給皂液機(jī)項(xiàng)目提案報(bào)告模范
- 2025年農(nóng)業(yè)資源共享與協(xié)同發(fā)展協(xié)議
- 2025年建筑工程中介服務(wù)合同模板
- 2025年農(nóng)產(chǎn)品銷售合作協(xié)議合同
- 2025年棉花加工成套設(shè)備項(xiàng)目立項(xiàng)申請報(bào)告模稿
- 數(shù)字出版概論 課件 第七章 數(shù)字內(nèi)容服務(wù)相關(guān)技術(shù)
- 信號與系統(tǒng)復(fù)習(xí)題(答案全)
- 《2024版CSCO胰腺癌診療指南》更新要點(diǎn)
- 兒童福利機(jī)構(gòu)安全管理規(guī)范
- 第1課 おじぎ 課件高中日語人教版第一冊-1
- ISO∕IEC 23894-2023 信息技術(shù) -人工智能 - 風(fēng)險(xiǎn)管理指南(雷澤佳譯-2024)
- 六年級下冊語文第一單元測試卷 部編版(含答案)
- 2024年湖南高速鐵路職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫新版
- 醫(yī)學(xué)人體美學(xué)的測量和評估
- 2024年湖南生物機(jī)電職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫及答案解析
- FZT 51006-2012 膜級聚己內(nèi)酰胺切片
評論
0/150
提交評論