posts - 3,  comments - 5,  trackbacks - 0

                  Jbpm,他是jboss下的一個(gè)開(kāi)源項(xiàng)目,是個(gè)基于petri net理論為基礎(chǔ)的工作流引擎。本文主要通過(guò)jbpm源代碼分析下jbpm引擎內(nèi)核工作原理。
                  Jbpm是基于微內(nèi)核引擎的基礎(chǔ)上擴(kuò)展開(kāi)發(fā)出來(lái)的工作流平臺(tái),其運(yùn)行的核心包是在org.jbpm.graph下,在該包下又分有action、def、exe、log、node幾個(gè)包,jbpm內(nèi)核引擎實(shí)現(xiàn)邏輯主要存放在def、exe這兩個(gè)包下,其他的包是基于此內(nèi)核擴(kuò)展出來(lái)的動(dòng)作、模型和日志。
                  下面我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)逐步的分析jbpm是如何工作的。看下面jbpm自帶演示的一個(gè)hello流程(視乎大家都喜歡從hello實(shí)現(xiàn)開(kāi)始^_^),代碼如下:
                  public void testHelloWorldProcess() {
                          ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
                          "<process-definition>" +
                          " <start-state>" +
                          " <transition to='s' />" +
                          " </start-state>" +
                          " <state name='s'>" +
                          " <transition to='end' />" +
                          " </state>" +
                          " <end-state name='end' />" +
                          "</process-definition>"
                          );

                          ProcessInstance processInstance =new ProcessInstance(processDefinition);
                          Token token = processInstance.getRootToken();
                          assertSame(processDefinition.getStartState(), token.getNode());
                          token.signal();
                          assertSame(processDefinition.getNode("s"), token.getNode());
                          token.signal();
                          assertSame(processDefinition.getNode("end"), token.getNode());
                  }
                  首先,我們定義個(gè)流程模板(ProcessDefinition),就是上面代碼的ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(….);這段,在括號(hào)中是jbpm定義的流程,其中包括三個(gè)環(huán)節(jié),分別是starts-state、state和end-state。parseXmlString()方法的主要功能是解析這段xml語(yǔ)言返回個(gè)流程模板對(duì)象(processDefinition)。
                  接著,通過(guò)流程實(shí)例類(ProcessInstance)來(lái)實(shí)例化個(gè)流程實(shí)例,通過(guò)傳進(jìn)來(lái)的流程模板對(duì)象創(chuàng)建ProcessInstance processInstance =new ProcessInstance(processDefinition)。我們來(lái)看看new ProcessInstance(processDefinition)到底做了什么,通過(guò)查看ProcessInstance的源代碼,可以看到其中主要的一段是
                  public ProcessInstance( ProcessDefinition processDefinition ) {
                      //略去其他代碼
                      this.processDefinition = processDefinition; //將流程模板對(duì)象付給流程實(shí)例
                      this.rootToken = new Token(this); //創(chuàng)建跟令牌
                      //略去其他代碼
                  }
                  我們繼續(xù)跟進(jìn)Token這個(gè)類
                  public Token(ProcessInstance processInstance) {
                      //主要一句如下
                      this.node = processInstance.getProcessDefinition().getStartState();
                  }
                  這樣就實(shí)現(xiàn)了令牌綁定到開(kāi)始節(jié)點(diǎn)。至此,一個(gè)流程實(shí)例就創(chuàng)建起來(lái)了,并且該流程實(shí)例走到了開(kāi)始節(jié)點(diǎn),即令牌所處的位置。
                  我們接著往下走token.signal()
                  public void signal() {
                          signal(node.getDefaultLeavingTransition(), new ExecutionContext(this));
                          //這里的getDefaultLeavingTransition()如果有多條路徑,則去第一條路徑
                    }
                  void signal(Transition transition, ExecutionContext executionContext) {
                      //省略其他代碼
                      node.leave(executionContext, transition);
                      //省略其他代碼
                  }
                  這里的node就是剛才令牌所在的開(kāi)始節(jié)點(diǎn),我們來(lái)看看jbpm是如何將令牌從開(kāi)始節(jié)點(diǎn)移到下個(gè)節(jié)點(diǎn)的。
                  public void leave(ExecutionContext executionContext, Transition transition) {
                      Token token = executionContext.getToken();
                      token.setNode(this);//此時(shí)令牌還在開(kāi)始節(jié)點(diǎn)
                      executionContext.setTransition(transition);
                      //略去部分代碼
                  executionContext.setTransitionSource(this);
                  transition.take(executionContext);//實(shí)現(xiàn)令牌的轉(zhuǎn)移
                  }
                  我們來(lái)看看transition.take(..)方法做了什么
                  public void take(ExecutionContext executionContext) {
                      //略去部分代碼
                      to.enter(executionContext);//離開(kāi)開(kāi)始節(jié)點(diǎn),進(jìn)入到下個(gè)節(jié)點(diǎn)
                  }
                  大家可能會(huì)有點(diǎn)疑問(wèn),這個(gè)to節(jié)點(diǎn)是什么是否初始化的?其實(shí)在signal時(shí)有句node.getDefaultLeavingTransition(),這句返回Transition對(duì)象,該對(duì)象就已經(jīng)初始化了to節(jié)點(diǎn)的對(duì)象。我們?cè)诟M(jìn)to.enter(..)
                  public void enter(ExecutionContext executionContext) {
                      Token token = executionContext.getToken();
                      token.setNode(this);//此時(shí)令牌就到了名字為“s”的state節(jié)點(diǎn)
                      token.setNodeEnter(new Date());
                      executionContext.setTransition(null);
                      executionContext.setTransitionSource(null);
                      execute(executionContext);
                  }
                  在這段代碼中的注釋這句,真正實(shí)現(xiàn)了令牌從開(kāi)始節(jié)點(diǎn)到下個(gè)節(jié)點(diǎn)了。
                  至此,jbpm工作流引擎的內(nèi)部工作原理就介紹完了,其實(shí)這就是工作流引擎最核心的部分了,就是如何從一個(gè)環(huán)節(jié)轉(zhuǎn)移到另一個(gè)環(huán)節(jié)。或許你會(huì)說(shuō)“這么簡(jiǎn)單,我馬上就可以寫(xiě)一個(gè)”,其實(shí)不然,上面我們所用的例子是十分簡(jiǎn)單的例子,其實(shí)在工作流聯(lián)盟規(guī)范中還有其他復(fù)雜的節(jié)點(diǎn)模型,如split,join,subflow等。不過(guò)幸運(yùn)的是這些復(fù)雜的節(jié)點(diǎn)模型jbpm都為我們提供了他自己的默認(rèn)的實(shí)現(xiàn),這些節(jié)點(diǎn)模型都在org.jbpm.graph.node包下。jbpm引擎中很好的抽象了節(jié)點(diǎn)模型Node類,大部分的復(fù)雜節(jié)點(diǎn)模型都繼承自Node,我們也可以定制自己的節(jié)點(diǎn),只要實(shí)現(xiàn)Node類的execute()方法即可方便的實(shí)現(xiàn)。其實(shí)從上面分析的代碼可以看出,Node類主要的邏輯處理是在leave()、enter()和execute()三個(gè)方法,大家可以看下ProcessState,join,fork這些節(jié)點(diǎn)模型是如何實(shí)現(xiàn)的。
          以上簡(jiǎn)單介紹了jbpm引擎內(nèi)核的工作原理,如有不對(duì)的地方還望指正。

          posted on 2008-09-16 19:28 囧囧之豬 閱讀(4207) 評(píng)論(5)  編輯  收藏 所屬分類: workflow

          FeedBack:
          # re: 【原】通過(guò)jbpm源碼分析jbpm引擎內(nèi)核工作原理
          2008-09-17 00:03 | mingj
          不錯(cuò)
          其實(shí)工作流引擎最難的是流轉(zhuǎn)的定義和抽象
          1. 如何將復(fù)雜的業(yè)務(wù)流程抽象成線性, 分支或合并的圖形學(xué)關(guān)系
          2. 如何提供dsl或腳本語(yǔ)言讓業(yè)務(wù)專家編寫(xiě)工作流規(guī)則  回復(fù)  更多評(píng)論
            
          # re: 【原】通過(guò)jbpm源碼分析jbpm引擎內(nèi)核工作原理
          2008-09-17 01:36 | 站長(zhǎng)論壇
          教程真詳細(xì),謝!  回復(fù)  更多評(píng)論
            
          # re: 【原】通過(guò)jbpm源碼分析jbpm引擎內(nèi)核工作原理
          2008-09-17 09:33 | yz
          寫(xiě)得好,支持一下!繼續(xù)努力  回復(fù)  更多評(píng)論
            
          # re: 【原】通過(guò)jbpm源碼分析jbpm引擎內(nèi)核工作原理
          2008-09-17 14:16 | 昨夜流星
          分析的不錯(cuò),呵呵,樓主文中提到了:“jbpm引擎中很好的抽象了節(jié)點(diǎn)模型Node類,大部分的復(fù)雜節(jié)點(diǎn)模型都繼承自Node,我們也可以定制自己的節(jié)點(diǎn),只要實(shí)現(xiàn)Node類的execute()方法即可方便的實(shí)現(xiàn)。”,不知道樓主能不能給個(gè)擴(kuò)展的例子,感謝之至!  回復(fù)  更多評(píng)論
            
          # re: 【原】通過(guò)jbpm源碼分析jbpm引擎內(nèi)核工作原理
          2012-08-13 13:57 | 我是樓主
          這段文章怎么我在哪個(gè)文檔上面看過(guò)。 不是樓主自己寫(xiě)的吧? 不過(guò)的確是把jbpm的核心部分寫(xiě)出來(lái)了  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2012年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          相冊(cè)

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 上饶市| 循化| 曲沃县| 彭阳县| 宜兴市| 阳西县| 沈丘县| 崇信县| 德昌县| 新津县| 营山县| 林口县| 新乐市| 广南县| 灌南县| 乌拉特前旗| 盐山县| 华宁县| 东丽区| 甘洛县| 平谷区| 贺州市| 博客| 启东市| 武冈市| 甘泉县| 阳信县| 甘肃省| 塔城市| 盐池县| 清徐县| 洪洞县| 浙江省| 大兴区| 方山县| 西盟| 根河市| 金秀| 九江市| 兴城市| 项城市|