JBPM流程引擎

揭祕 jbpm 流程引擎內核設計思想及構架
做者 胡長城(銀狐999)
 
1     前言
2.1      概念的基礎
2.2      環境的基礎
4.1      模型與定義對象
4.2      調度機制與算法
4.3      執行機制與狀態
4.4      實例對象與執行環境
6.1      首先解決如何形式化描述一個流程的問題
6.2      抽象的節點(Node)和轉移(Transition
6.3      流程:節點與轉移的組合
6.4      節點的類型和擴展
7.1      吸納自Petri Net思想
7.2      Token的推動
7.3      很是簡單的調度機制
8.1      執行機制
8.2      分支處理
10       後記
 

1       前言

 

       流程引擎內核僅是「知足 Process 基本運行」的最微小結構,而整個引擎則要複雜不少,包括「狀態存儲」、「事件處理」、「組織適配」、「時間調度」、「消息服務」等等外圍的服務性功能。 引擎內核,僅包含最基本的對象和服務,以及用於解決流程運行問題的調度機制和執行機制。
       若是,你掌握了一個流程引擎的靈魂,你纔有能力理解它的所有。不然,一個引擎對你來講,可能只是一個複雜的結構,豐富多彩API、使人眼花繚亂的「功能」和「服務」而已。
 
       自己工做流這個領域就是一個很「狹窄」的領域,國內的廠商也不是不少,其中有部分實現技術並不弱。但 可能涉於安全等因素,並無多少技術人員探討「深度的工做流技術實現問題」。而廣大的開發愛好者卻還在花費大量的時間在摸索「如何理解工做流、如何應用工 做流」。 因此在此以前,國內還沒有有一篇技術文章探討工做流引擎內核的實現,固然也沒有探討jBpm引擎內核的文章了。在 www.javaeye.com 技術站點和個人blog( http://blog.csdn.net/james999)上有幾篇專門探討jbpm應用的文章,對於初步想了解如何使用jbpm的讀者來講,值得看看。
 
       對於這方面的技術分享,開源是個不錯的突破口。
       本篇就是以jBpm爲實例,來詮釋工做流引擎的內核設計思路和結構。可是這僅僅是從jBpm的實現角度來輔助你們理解,由於工做流引擎內核的設計、實現是有不少方式:這 會因所選的模型、調度算法、推動機制、狀態變遷機制、執行機制等多方面的不同,而會差異很大。好比基於Activity Diagram模型的jBpm和基於FSM模型的OSWorkflow引擎內核之間就有很大的差異。
       相比較而言,jBpm的模型比較複雜,而引擎內核實現的比較「精簡」,很是便於你們「由淺入深的理解」。

2       閱讀本篇的基礎準備

2.1    概念的基礎
       本文的讀者羣主要是面向有必定工做流基本概念的開發人員。因此本文認爲你已經具有了以下基本工做流知識:
(1)       初步瞭解工做流系統結構。好比理解工做流引擎在工做流系統中所處的位置和做用
(2)       對流程定義(Process Definition)和流程實例(Process Instance)相關對象有所瞭解。好比理解Process Instance表明什麼,工做項(WorkItem)表明什麼。

2.2    環境的基礎
       在閱讀本篇的時候,若是你已經搭建了一套jbpm的開發環境,那麼將有助於你更容易理解本篇的不少內容,也便於實際體驗代碼。從 www.jbpm.org官方網站下載jbpm-starters-kit開發包,按照其參考手冊,能夠很容易在eclipse開發環境中創建項目,效果圖相似以下:

 

3       什麼是流程引擎內核?

       我比較推崇「微內核的流程引擎構架」,並在最近兩三年內寫了兩篇探討此方面的文章:第一篇是寫於05年7月份的《微內核流程引擎架構體系》,第二篇是07年7月份的《微內核過程引擎的設計思路和構架》(受普元《銀彈》雜誌約稿所寫,還沒有對外公開)。
       但至今對外闡述引擎內核究竟是什麼。
  
 
       正如上面的兩張圖所示,咱們能夠經過「微內核」的構架來使得流程引擎的結構更加「清晰」。而可否實現「微內核」的根本,則是看你是否可以設計並抽象出「良好的引擎內核結構」。
 
       很顯然,要想設計出一套結構優良的引擎內核,首要條件就是:明白什麼是引擎內核。
 
       首先咱們須要明白引擎是什麼,引擎能夠作什麼。這在WfMC的《工做流參考模型》中已經有很詳細的解 答,本文再也不重複。知道這個僅僅是不夠的,你還須要很清晰的明白如何去「爲流程建模」,而這則在Aalst大師所著的《工做流管理——模型、方法、系統》 一書有細緻闡述,本文也再也不重複。
       但很惋惜,至今還沒有有一本專門的書籍來論述「過程建模方法」的,或者說如何利用這些既有的「過程建模方法(諸如FSM、PetriNet、EPC、Activity Diagram等等)」來解決流程問題。這個只能分別查閱相關資料,此處也不敘述。
       由於文本只講「引擎內核」。
 
       若是咱們暫且把那複雜的流程業務性問題,諸如「組織模型分配」、「分支條件計算」、「事件處理」、「消息調度」、「工做項處理」、「存儲」、「應用處理」、以及那些「變態的諸如會籤、回退之類的模型」都通通的拋棄, 只留下「最單純的過程性問題」,也就是「解決一個過程運行問題,按秩序的從一個節點到另外一個節點的執行」。—— 這就是引擎內核所關注的根本問題。
       上面這句話,估計會引發不少人「拍磚」。在不少人看來,工做流之因此看起來很「難」,就是由於這些複雜多變的「業務性問題」都通通綁在一個「引擎」上形成的。
       其實,這是兩個「維度」的問題,也就是「引擎的抽象」和「引擎的應用」這兩個不一樣維度,不一樣層面的問 題。但這毫不是兩個獨立的問題,「引擎的抽象」的好與壞,直接影響到「引擎的應用」的可複雜度和可支持度,固然咱們也不可否認,「引擎的應用」問題也是一 個很複雜的問題。但本文是站在「引擎的抽象」這個維度來闡述問題的。對於「引擎的應用」問題,可參考個人前做:2003年11月份的《工做流模型分析》、 2003年12月份的《工做流受權控制模型》、2004年7月份的《工做流系統中組織模型應用解決方案》。
       也就是說,本文不是指導你們如何去「使用jbpm」,而是闡述「jbpm的引擎的內核部分是如何構建的」。但本文的主旨不是告訴你們「jBpm是如何設計引擎內核的」,而是以jBpm爲例,來介紹「引擎內核」。
 

 4       引擎內核所關注的四個主要問題

       引擎內核所關注的是一個很是「抽象」層面的問題,而不一樣引擎關注的「一套完整的執行環境」。或者咱們能夠這麼來講,引擎內核的職責是很是「精簡」的:確保流程按照既有的定義,從一個節點運行到另外一個節點,並正確執行當前節點。
       總的來講,引擎內核主要關注四個方面的問題:
(1)       流程定義問題:不是說如何圖形化的定義流程,而是如何用一套定義對象,來詮釋所定義的流程。
(2)       流程調度問題:提供什麼的機制,能夠確保流程可以處理複雜的「流程圖結構」,諸如串行、並行、分支、聚合等等,並在這複雜結構中確保流程從一個節點運行到另外一個節點。
(3)       流程執行問題:當流程運行到某個節點的時候,須要一套機制來解決:是否執行此節點,並如何執行此節點的問題,並維持節點狀態生命週期。
(4)       流程實例對象:須要一整套流程實例對象來描述流程實例運行的狀態和結果。

4.1    模型與定義對象
       工做流引擎自己就是一種「base on model」的組件,流程實例的執行都是依賴於所定義的「流程定義」,而工做流引擎則是提供了這樣一種環境,來維持流程實例的運行。
       因此引擎內核,必須提供一套定義對象來描述「流程定義」,而且這些定義對象必須反映出一種「模型」。
       好比jBpm的定義對象,是與其所基於的Activity Diagram模型相對應的。

4.2    調度機制與算法
       引擎內核的另外一個重要功能,就是保證流程實例準確的從一個節點運行到另外一個節點,而這則須要依賴於一套調度機制。
       引擎的調度機制有不少種實現方法,有的甚至是與「所依賴的模型有關」。但廣泛來說,不少引擎都受到Petri Net的影響,而採用token來調度。
       jBpm自己就吸納的token這套機制,固然,與Petri Net的調度機制仍是有所區別。咱們將在下面的章節詳細介紹。

4.3    執行機制與狀態
       通過引擎的調度,實例運行到某個節點了,此時必須必須提供一套機制,來判斷當前節點是否可執行,若是可執行,那麼須要提供一套runtime envrioment來執行節點——這就是引擎的執行機制。
       複雜的流程引擎會依賴於「流程實例狀態」或「活動實例狀態」的約束和變遷來進行處理。之全部有時候咱們會把一個流程引擎也叫作「狀態機」,很大程度上也是這個緣由。

4.4    實例對象與執行環境
       每一個一個流程實例,必須維護一套屬於本身的「運行環境和數據」,而這則是實例對象的責任了。基本上實例對象會包含以下信息:
(1)       與流程實例的狀態或控制信息
(2)       與活動實例的狀態或控制信息。若是某些引擎不支持活動實例,那麼必然會有某些其餘實例信息,能夠當前節點的狀或控制信息。
(3)       一些臨時的「執行」信息,便於引擎針對某種狀況進行處理
 

 5       jbpm,「精簡」的開源流程引擎

       好的開源工做流引擎很少,jbpm和osworkflow算是其中兩個有特點並且比較容易實際應用 的。目前一些國內的中小型流程應用項目,就是在jbpm或osworkflow的基礎上擴展實現。jBpm採用了Activity Diagram的模型,而osworkflow則是FSM的模型。
       固然,這僅僅是jbpm3以後的事情。自從被Jboss收購以後,jbpm對早先的2.0構架進行了重組,整個結構徹底本着「微內核」的思想進行設計。
       如今這裏從技術角度來分析jbpm3的優勢,簡單羅列幾個你們都容易看見的:
(1)       jbpm的模型是採用UML Activity Diagram的語義,因此便於開發人員理解流程。
(2)       jbpm提供了可擴展的Event-Action機制,來輔助活動的擴展處理。
(3)       jbpm提供了靈活的條件表達式機制,來輔助條件解析、腳本計算的處理。
(4)       jbpm提供了可擴展的Task及分配機制,來知足複雜人工活動的處理。
(5)       藉助hibernate的ORM的優點,jbpm可以很容易支持多種數據庫。
 
固然,還有一些優勢,是不少開發人員並不太注意的,好比:
(1)       jbpm的Node機制很是靈活,開發人員能夠很容易定製「業務化語義的節點」,並知足運行時候處理的須要。
 
有不少靈活的優勢,固然也少不了存在一些「侷限」。
(1)       很顯然,只能有一個start-state。
(2)       jbpm依靠Token來調度和計算,在同一個時刻中,一個ProcessInstance只容許一個Token對象只存在一個Node中(分支固然用Child Token對象處理)。因此本質上就不支持「multi-instance」模式。
(3)       jbpm做爲一款開源的工做流引擎,其更多的是關注「如何輔助你更容易的讓流程運行完成」,可是並不記錄「流程運行的歷史和軌跡」。這一點多是東西方文化的差別性所在,由於國內的流程應用,比較關注「運行軌跡」。
 
       至於其餘的一些侷限,好比不支持「回退」、 「跳轉」等操做,這也是由於東西方文化的差別所在。西方人認爲「往回流轉的狀況確定也是一種業務規則所定義,那麼確定能夠經過分支或條件來解決」,而東方 則把「回退做爲一我的性化管理和處理的潛在特色」。因此諸如此類的一些「特定需求」,估計只能經過擴展jbpm來實現了,甚至有時候,簡單的擴展是沒法解 決問題的——正如上一節所說的那樣,「引擎的抽象」會影響「引擎的應用」的複雜度支持。
       可是,當你試圖修改jbpm代碼的時候,你會顧慮jbpm的LGPL協議嗎?(不少國內企業歷來不考慮這個協議問題,寒)。
 

 6       jBpm流程模型與定義對象

6.1    首先解決如何形式化描述一個流程的問題
       這裏說的「定義流程」並非說jbpm3中那個基於eclipse plugin的圖形化建模工具。而是 如何去解決「形式化的描述一個流程」的問題。
       形式化的描述流程並非一個簡單的問題,從上世紀七十開始,人們就在探索用各類各樣多的模型來描繪流 程:Petri Net, FSM, EPC, Activity Diagram, 以及近來的XPDL MetaModel等等,延伸到現在的BPEL,BPMN,BPMD等等。
        jBpm採用了Activity Diagram的模型語義:其將用Start State、State、Action State(Task Node)、End State、Fork、Join、Decision、Merge、Process State這幾個「元素」的組合來描述任何一個流程。其中Action State是Activity Diagram中的標準語義,在jBpm爲了便於你們理解和使用,jBpm採用了TaskNode這個語義。
 
       在WfMC的Workflow Reference Model中,對流程引擎的功能描述,其中就包含一項:解析流程定義。若是想知足這這功能,前提條件就必須有最基本的兩個:
(1)       有一套形式化的描述語言(一般爲xml格式)。利用這個描述語言能夠描述一個流程的定義。好比WfMC所提出的XPDL這個描述語言。固然,jBpm也有本身的一套,名爲jPDL,也是一個xml格式的。
(2)       有一套對象集能夠反映流程的定義模型和結果,通常叫作定義對象。流程引擎就須要把「xml格式的流程定義」解析爲一套對象,而這套對象的結構則反映了流程的結構。
      
       咱們暫且不去探討jPDL那個形式化的xml語言,而把重心放在jBpm那套定義對象中。由於這個定義對象是屬於Engine Kernel的一部分。
6.2    抽象的節點(Node )和轉移(Transition
       面向對象的繼承性、多態性可讓咱們從最抽象的部分來描述對象。那麼這套定義對象也須要從最基礎的「抽象」提及。
       process 的本質就是「節點」和「有向弧」 固然你也能夠說是Node和Link,或者Node和Transition,或者Activity和Transition等等之類的。jBpm採用的是Node和Transition來表示「節點」和「有向弧」。
       因而乎,在jbpm中你能夠看到這樣的結構關係:
       對於一個節點來講,從定義角度,其只關心幾個事情:
(1)       這是個什麼類型的節點。這個節點多是start state,也多是一個task node,或者是一個fork。
(2)       這個節點的轉入Transition和轉出Transition。
       可能有的人會說,還須要關心節點的轉入轉出的類型,好比And Splite或者Xor Join之類。這個並無錯,由於不少流程模型的節點元素須要考慮這個,好比WfMC的XPDL模型。可是jBpm的節點是沒有這樣的屬性的,或者說的更 準確些,是Activity Diagram模型的節點沒有這樣的特性。活動圖是採用「Fork」、「Join」這樣的節點來解決「分支」問題。
6.3    流程:節點與轉移的組合
       僅利用節點和轉移的組合,就能夠表達一個「過程(Process)」。固然這個流程只能告訴人們「大概的業務過程」,固然不包括很複雜的信息。以下圖所示:
       這是一張很是標準的「活動圖」,若是咱們用jbpm的設計器,看看這樣一張「流程圖」:
 
       不論你如何繪畫,改變不了這張圖的本質:它就只有兩個基本元素:節點和轉移。只是有的節點是start-state,有的是task-node,有的是join,有的是end state而已。
6.4    節點的類型和擴展
       咱們能夠經過定義本身的Node節點對象,來補充jbpm自定的節點對象。只須要extends Node,並重寫讀寫xml的read和write方法,重寫負責執行的execute方法,在org/jbpm/graph/node /node.types.xml中配置便可,固然,你能夠寫的更加複雜,更加業務化的節點。

7       jBpm的過程調度機制

7.1    吸納自Petri Net 思想
       jBpm的過程調度機制是吸納了Petri Net的一些思想。
       jBpm採用Token來表示當前實例運行的位置,也利用token在流程各個點之間的轉移來表示流程的推動,以下圖所示:
 
       當jbpm試圖去啓動一個流程的時候,首先是構造一個流程實例,併爲此流程實例建立一個Root Token,並把這個Root Token放置在Start Node上。
       如下截取部分代碼實現,僅供參考。手頭有jbpm3相應開發環境的朋友,能夠打開ProcessInstance和Token這兩個類。(注:如下全部參考代碼,爲了突出主題,都已經將實際代碼中的event,log等處理刪除)
public ProcessInstance( ProcessDefinition processDefinition ) {
    this.processDefinition = processDefinition;
    this.rootToken = new Token(this);
 
public Token(ProcessInstance processInstance) {
    this.processInstance = processInstance;
    this.node = processInstance.getProcessDefinition().getStartState();
       jbpm是容許在start-state執行Task的,也容許在start-state建立工人任務。不過此處咱們不予討論。
7.2    Token 的推動
       當Token已經在Start-State節點了,咱們能夠開始往前推動,來促使流程實例往前運行。對於外部操做來講,觸發流程實例往下運行的操做有兩個:
(1)       強制執行ProcessInstance的signal操做
(2)       執行TaskInstance的end操做。
可是,這兩個操做,都是經過「當前token的signal操做」來內部實現的,以下圖所示:
 
       Token Signal 操做表示:實例須要離開當前 token 所在的節點,轉移到下一個節點上。由於 Node Node 之間是「 Transition 」這個橋樑,因此,在轉移過程當中,會首先把 Token 放入相關連的 Transtion 對象中,再由 Transition 對象把 Token 交給下一個節點。

       讓咱們來看看Token類中signal方法的部分代碼實現,僅供參考:
public void signal() {
    // 注意 ExecutionContext 對象
    signal(node.getDefaultLeavingTransition(), new ExecutionContext(this));
}

void signal(Transition transition, ExecutionContext executionContext) {
    // start calculating the next state
    node.leave(executionContext, transition);
}
 
       接下來,請注意node.leave()這個操做。這是一個頗有意思的語義轉換:咱們是採用token的signal操做來表示往下一個節點推動,可是實際確實執行的node.leave ()操做。
 
       若是這地方讓你本身來實現,代碼會不會就是這樣子呢?不妨此處想想。
// 假設代碼,僅供思考
void signal(Transition transition, ExecutionContext executionContext) {
    transition.take(executionContext);
}
 
       前面說過,jbpm的調度機制吸納的Petri Net的思想。在Petri Net中,並無transition中駐留token這個語義,token只駐留在庫所(Place)中。因此,jbpm此處的設計思路,是於此有必定 關係的。因此只是把一個ExecutionContext對象放在了transition中,而不是一個token對象。
       讓咱們來看看node對象的leave方法:
public void leave(ExecutionContext executionContext, Transition transition) {
    Token token = executionContext.getToken();
    token.setNode(this);
    executionContext.setTransition(transition);
    executionContext.setTransitionSource(this);
    transition.take(executionContext);
}
              咱們直接跟蹤進Transition的take操做:
public void take(ExecutionContext executionContext) {
    executionContext.getToken().setNode(null);
    // pass the token to the destinationNode node
    to.enter(executionContext);
}
             
       通過這麼多的中間步驟,咱們終於把ExecutionContext對象從一個node轉移到下一個node了。讓咱們來看看Node對象的enter操做:
public void enter(ExecutionContext executionContext) {
    Token token = executionContext.getToken();
    token.setNode(this);
    // remove the transition references from the runtime context
    executionContext.setTransition(null);
    executionContext.setTransitionSource(null);
 
    // execute the node
    if (isAsync) {
     
    } else {
      execute(executionContext);
    }
}
 
       至此,jBpm成功的從一個節點轉移到下一個節點了。—— 這就是jbpm的調度機制。
7.3    很是簡單的調度機制
       怎麼樣,是否是很是的簡單?
       讓咱們把整個過程,用一張更清晰的「思惟圖」來展現一下:


8       jBpm的過程執行機制

8.1    執行機制
       前面咱們的「過程調度機制」是爲了讓流程能夠正確的從「一個節點轉移到下一個節點」,而本節所要講解的jbpm「執行機制」,則是爲提供一個運行機制,來保證「節點的正確執行」。
       首先咱們須要明確以下的概念:
(1)       節點有不少中,每種節點的執行方式確定是不同的
(2)       節點有本身的生命週期,不一樣的生命週期階段,所處的狀態不一樣。
 
       在WfMC的《工做流參考模型》文檔中,爲活動實例概括了幾個可參考的生命週期。(僅供參考,實際不少工做流引擎的節點的生命週期要比這複雜)
 
       可是,jbpm並無突出「節點生命週期」這個理念,僅僅只是在「Event」中體現出出來。在我看來,可能的緣由有兩個:
(1)       jBpm 沒有 NodeInstance 這個概念。利用Token和TaskInstance,jBpm足以持久化足夠的信息,可以讓流程實例迅速定位到當前運行的狀態。
(2)       jBpm的Event已經很豐富,而且這個Event是圍繞「Token的轉移」而設置的,並非圍繞Node的生命週期設置的。
(3)       一般咱們須要在Active和Completed的生命週期內所要操做的分支與聚合,在jBpm模型中分別由Fork、Join之類的節點替代。因此jBpm過度關注Node生命週期的管理意義不是很是大。
 
       做爲我的,我並不行賞jBpm這樣拋棄「節點生命週期管理」的實現方式,更行賞OBE(最先的基於 XPDL模型的java工做流引擎之一)的生命週期約束和管理。可是,也不得不認可,jBpm規避了「繁瑣的狀態維護」,反而讓處理變得「簡易」,也更容 易被你們所理解和接受,而這也正是OBE逐漸消失的一個緣由:過於複雜和臃腫。
      
      
讓咱們在前面那張jBpm的「調度機制思惟圖」上,再稍稍補充一點(爲了突出顯示,與上圖有所改動)。

       這張圖應該能夠很好的詮釋出,jBpm是如何執行各類節點的,這也是得益於OO的「多態與繼承」特性。
 
8.2    分支處理
       jBpm的執行機制很是簡單,但仍是須要稍微補充一下有關「分支」方面的處理。
       jBpm採用sub token的機制來解決分支方面的處理:當遇到有分支的時候,會爲每一個分支節點建立一個child token。在聚合節點(Join或Merge),則依賴其同步或異步的聚合方式,來分別處理。
       好比咱們參看Fork節點的執行代碼(爲了突出重點,省略部分代碼):
public void execute(ExecutionContext executionContext) {
    Token token = executionContext.getToken();
    Iterator iter = transitionNames.iterator();
    while (iter.hasNext()) {
      String transitionName = (String) iter.next();
      forkedTokens.add(createForkedToken(token, transitionName));
    }
    iter = forkedTokens.iterator();
    while( iter.hasNext() ) {
      // 省略部分代碼
      ExecutionContext childExecutionContext = new ExecutionContext(childToken);
      leave(childExecutionContext, leavingTransitionName);
    }
}
 
protected ForkedToken createForkedToken(Token parent, String transitionName) {
    Token childToken = new Token(parent, getTokenName(parent, transitionName));
    forkedToken = new ForkedToken(childToken, transitionName);
    return forkedToken;

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
       至於Merge節點,我想此處不用在累贅的展現,有興趣的,能夠參看Merge類的execute方法,便可。
 

9       jBpm內核結構與實例對象

       Jbpm引擎內核的結構很是「精簡」。除了咱們上面所說的那些定義對象(各類Node節點和Transtion),還有幾個與「運行實例」相關的對象。以下圖所示,jbpm引擎內核對象主要是在org.jbpm.graph.def和org.jbpm.graph.exe包。
(1)       咱們須要描述一個流程實例,因此須要一個ProcessInstance對象。
(2)       每一個流程實例,都會維護一套屬於其本身的「執行環境」,也就是ExecutionContext對象。注意,這裏是一套,而不是一個。
 

10   後記

       上半年寫了些bpm和SOA的文章,也被csdn的好友拉着忽悠了很多這方面的概念,弄的好像我開始 搞這方面的工做似的。其實否則,本質工做與這有「天壤之別」,徹底是很是底層的java技術應用。而workflow,也有兩三年沒有從事這方面的開發 了,因此寫此篇文章,着實費了點功夫。
       想痛痛快快寫篇有關「引擎內核」的文章,這個想法由來以及了,卻擔憂本身不足以詮釋清楚,反而容易誤導他人,遂中途屢次放棄。
       正如前面所說的那樣,引擎內核的實現,並無一套「固定的模式」或者「固定的實現體系」,會由於不少因素而形成實現不一樣。若是想把「引擎內核」的實現真正詮釋清楚,必須把這些相關因素都詮釋明朗——但這依然是一個浩大的工程。
       前些日子,受朋友所託,爲他們的公司學員講了幾節工做流的課程,期間嘗試jBpm來詮釋了一下引擎的實現思路,發現效果不錯。——受此引起,遂萌發了以jBpm爲實例,來簡單詮釋「流程引擎內核」想法。
       耗時一週的業餘時間,雖然還很難詮釋本身的所有想法,但「點出幾個要點」,仍是應該有了。
 
                                                                                           胡長城
                                                                                           寫於2007年9月2日星期日 夜。
本文揭祕了jbpm引擎內核的設計思想和構架,但不是jbpm引擎的所有。請注意是「流程引擎內核」,而不是「流程引擎」。若是咱們把流程引擎比做工做流系統的「發動機」,那麼「引擎內核」則是一個引擎的「靈魂」。
 ====================================================================
聲明:本文首發csdn blog,轉載請註明做者信息及原文地址,謝謝

做者信息:
胡長城(銀狐999)
TIBCO中國研發中心 Infrastructure Team
http://www.javafox.org
http://blog.csdn.net/james999
相關文章
相關標籤/搜索