【增】JBOSS 工作流與JBPM開發(fā)實(shí)例

              大家好,下面由我來(lái)為大家介紹開源工作流引擎JBPM的初始化使用方法。

              首先當(dāng)你想學(xué)一個(gè)框架的時(shí)候一定是你要有項(xiàng)目來(lái)用他了,OK,那么你項(xiàng)目當(dāng)中的流程是什么你應(yīng)該清楚吧,那么當(dāng)你清楚了這些的時(shí)候我們就開始我們這個(gè)最簡(jiǎn)單的例子吧。

              假如我們現(xiàn)在有這么一個(gè)例子,公司員工想報(bào)銷點(diǎn)出差費(fèi),那么他要將他的申請(qǐng)?zhí)峤唤o他的第一級(jí)領(lǐng)導(dǎo)——部門主管去審批。

              然后部門主管審批完了之后還要交給這個(gè)部門主管的上級(jí)公司老總進(jìn)行審批。那么針對(duì)這個(gè)簡(jiǎn)單的流程,我們應(yīng)該從哪里下手呢?

              首先第一件事情就是寫流程定義文件,那么這個(gè)文件我們用什么來(lái)寫呢,他就是一個(gè)符合某個(gè)語(yǔ)法的xml文件,幸運(yùn)的是jbpm給我們提供了一個(gè)集成的開發(fā)環(huán)境讓我們來(lái)用。

              首先去官網(wǎng)上下一個(gè)jbpm-jpdl-suite-3.2.GA包,解壓后你會(huì)發(fā)現(xiàn)他里面有一個(gè)designer文件夾,那個(gè)里面就是我們寫流程定義文件的開發(fā)環(huán)境,他是一個(gè)eclipse的插件。

              但是好像他給我們的那個(gè)eclipse版本有問(wèn)題,建議大家從新下一個(gè)eclipse-SDK-3.2.1-win32.zip這個(gè)版本的eclipse,然后覆蓋他給我們提供的那個(gè)。

              準(zhǔn)備工作做完了,那么我們就開始吧,首先我們打開解壓目錄下的designer文件夾中的designer.bat文件,他彈出一個(gè)eclipse,然后我們就用這個(gè)東西來(lái)開發(fā)我們的流程定義文件了。


              打
          開之后你就會(huì)看見一個(gè)他的小例子,不過(guò)我們不去用他,我們自己新建一個(gè)工程。右鍵-new-other-jBoss jbpm-process project。這個(gè)時(shí)候你會(huì)看見他彈出一個(gè)對(duì)話框,輸入你的工程名字,然后點(diǎn)擊next,這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)他已經(jīng)把jbpm加載進(jìn)去了,記住要選中 Generate simple ......

              工程建立完了,我們開始建立我們的流程定義文件。在工程里面你會(huì)發(fā)現(xiàn)src/main/jpdl這個(gè)source folder,然后你會(huì)看見他里面已經(jīng)有了一個(gè)流程定義文件了,但是我們不去用他的。

              我們自己建立一個(gè),右鍵src/main/jpdl,然后new-other- jBoss jbpm-process definition。這個(gè)時(shí)候他就會(huì)彈出一個(gè)對(duì)話框,起一個(gè)你要寫的流程定義文件的名字輸入進(jìn)去,OK,可以了。這個(gè)時(shí)候你打開你建立的那個(gè)文件夾,里 面就有processdefinition.xml文件,ok,打開他。

              在右面的圖里面你就可以看到一張什么都沒(méi)有的白紙,我們看看這部分左面的那些東西,什么startendtasknodeforkjoin

              那我們來(lái)解釋一下這是個(gè)什么東西呢,我們看看我們的需求,員工要寫一個(gè)報(bào)銷單,然后交給部門主管來(lái)處理,那么部門主管就應(yīng)該算是一個(gè)tasknode,他就是一個(gè)任務(wù)節(jié)點(diǎn)。

              startend其實(shí)就是一個(gè)虛狀態(tài),當(dāng)我們寫完報(bào)銷單的時(shí)候我們就提交了,這個(gè)時(shí)候他就到了第一個(gè)tasknode這個(gè)節(jié)點(diǎn)了。然后他審批完了還要交給總經(jīng)理審批,那么他又是一個(gè)tasknode,然后總經(jīng)理審批完了結(jié)束,ok,是一個(gè)end

              start--
          tasknode(部門主管審批)--tasknode(總經(jīng)理審批)--end



              如果覺得看的有點(diǎn)模糊可以看看我傳上來(lái)的那個(gè)圖。然后你在這個(gè)試圖框的下面可以看到有個(gè)source,點(diǎn)擊一下,就會(huì)發(fā)現(xiàn)他已經(jīng)自動(dòng)的給你生成xml代碼了。

              但是這樣還是有點(diǎn)不夠,我們只是定義了一個(gè)tasknode節(jié)點(diǎn),并沒(méi)有定義tasknode節(jié)點(diǎn)的任務(wù)由誰(shuí)來(lái)做。那么我們還要定義一個(gè)tasknode節(jié)點(diǎn)是由誰(shuí)來(lái)做的:
          那么這段代碼是這么寫的:


              

          <?xml version="1.0" encoding="UTF-8"?>

          <process-definition
            xmlns
          =""  name="test1">
             
          <start-state name="start">
                
          <transition name="" to="部門經(jīng)理審批"></transition>
             
          </start-state>
             
          <task-node name="部門經(jīng)理審批">
                
          <task>
                 
          <assigment actorId="部門經(jīng)理"></assigment>
                
          </task>
                
          <transition name="" to="總經(jīng)理審批"></transition>
             
          </task-node>
             
          <task-node name="總經(jīng)理審批">
                
          <task>
                 
          <assigment actorId="總經(jīng)理"></assigment>
                
          </task>
                
          <transition name="" to="end1"></transition>
             
          </task-node>
             
          <end-state name="end1"></end-state>
          </process-definition>


          這樣的話我們的流程定義文件就定義完了,但是這只是把文件定義完了,系統(tǒng)并不知道啊,所以我們還要把我們的文件部署到系統(tǒng)中去。

           

          首先我們?cè)?/span>src/main/java里面新建立一個(gè)包,然后建立一個(gè)class,隨便起個(gè)名字,就叫 TestJBPM_01吧,那么在這個(gè)類里面我們要做的是什么呢?我們要先導(dǎo)入表,因?yàn)?/span>jbpm要運(yùn)行就要用到很多個(gè)表,ok,那么我們這個(gè)里面導(dǎo)入表和 hibernate導(dǎo)入表是差不多的,它的代碼是這樣的:

          package com.jbpm.test;
          import junit.framework.TestCase;
          import org.jbpm.JbpmConfiguration;
          public class TestJbpm_01 extends TestCase {
           
           
          public void testJbpm(){
            
            
          //創(chuàng)建jbpm數(shù)據(jù)庫(kù)表。他就像hibernate里面的哪個(gè)export一樣。實(shí)際上他就是hibernate里面的哪個(gè)export。
            
          //應(yīng)為他映射了很多個(gè)表,所以我們就能創(chuàng)建那么多個(gè)表。
            JbpmConfiguration.getInstance().createSchema();
            
           }
          }

              然后呢我們就開始部署我們的流程定義文件,我們將這個(gè)文件當(dāng)中的內(nèi)容呢放到數(shù)據(jù)庫(kù)當(dāng)中去,當(dāng)我們以后再用的時(shí)候呢我們就隨時(shí)的將它加載出來(lái)。

          package com.jbpm.test;
          import junit.framework.TestCase;
          import org.jbpm.JbpmConfiguration;
          import org.jbpm.JbpmContext;
          import org.jbpm.graph.def.ProcessDefinition;
          public class TestJbpm_02 extends TestCase {
           
           
          //jbpmConfiguration對(duì)象的創(chuàng)建
           static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
           
           
          public void testJbpm(){
            
            
          //然后我們把processDefinition里面相關(guān)的對(duì)象持久化到數(shù)據(jù)庫(kù)里面去。
            
          //流程定義文件里面有很多個(gè)概念,他有node,有transition,還有processDefinition,那么我們不需要一個(gè)
            
          //一個(gè)保存,jbpm把保存這么多對(duì)象的方法封裝成一個(gè)接口,叫做deployProcessDefinition。我們只要調(diào)用這個(gè)
            
          //方法,傳一個(gè)processDefinition對(duì)象,我們就能將他們存入到數(shù)據(jù)庫(kù)里面去。
            
            
          //這個(gè)首先第一步我們要得到一個(gè)processDefinition對(duì)象,然后我們把他部署到流程中去。
            ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("testJBPM/testJbpm.xml");
            
          //我們要存就必須獲得一個(gè)session對(duì)象,而jbpm已經(jīng)把session對(duì)象封裝到一個(gè)JbpmContext對(duì)象里面了。
            
          //那么這個(gè)jbpmContext對(duì)象是怎么得到的呢,我們要先有一個(gè)jbpmConfiguration對(duì)象,我們要對(duì)數(shù)據(jù)庫(kù)進(jìn)行
            
          //操作的時(shí)候一定要有jbpmConfiguration這個(gè)對(duì)象,用他來(lái)創(chuàng)建一個(gè)類似于hibernate當(dāng)中的session一樣的
            
          //對(duì)象——jbpmContext。他是我們對(duì)數(shù)據(jù)庫(kù)所有的操作的一個(gè)接口。
            JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
            
          try{
             
          //然后部署的操作已經(jīng)由jbpmContext給我們創(chuàng)建好了,我們只需要調(diào)一下他的一個(gè)方法就可以了。
             jbpmContext.deployProcessDefinition(processDefinition);
            }
          finally{
             
          //最后我們還要對(duì)他close一下,就像我們用hibernate的時(shí)候要close session一樣。
             jbpmContext.close();
            }
           }
          }

          第二步我們也做完了,那么現(xiàn)在我們開始做第三步,也就是說(shuō),我們流程定義文件寫好了,現(xiàn)在我們的系統(tǒng)當(dāng)中有了這樣一個(gè)報(bào)銷流程。

          那么就開始實(shí)際的去用她吧,一個(gè)人小報(bào)銷了,那么她就要寫一個(gè)報(bào)銷的申請(qǐng),但是這個(gè) 報(bào)銷的申請(qǐng)寫完了存到數(shù)據(jù)庫(kù)當(dāng)中了還不能算完了,應(yīng)該和我們的這個(gè)流程關(guān)聯(lián)起來(lái)啊,那么她應(yīng)該怎么去關(guān)聯(lián)呢,我們?cè)诮⑦@個(gè)申請(qǐng)單這個(gè)類的時(shí)候應(yīng)該定義一 個(gè)processInstanceId屬性,她是一個(gè)long型的。

          記錄這我們的這個(gè)流程實(shí)例的id,那么什么是流程實(shí)例 processInstance)呢,她是我們工作流當(dāng)中第二重要的概念,他和流程定義的關(guān)系就相當(dāng)于對(duì)象和類之間的關(guān)系,類是一個(gè)抽象的東西,她定義 完了是什么也干不了的,要想用她內(nèi)部定義的東西我們就要new出一個(gè)實(shí)例來(lái),當(dāng)然這個(gè)里面也是這樣的。

          那么也就是說(shuō),當(dāng)我們創(chuàng)建這個(gè)報(bào)銷申請(qǐng)的時(shí)候我們就要先根據(jù)這個(gè)流程‘new’出一個(gè)流程實(shí)例來(lái)存到數(shù)據(jù)庫(kù)當(dāng)中,然后在把她的id傳給報(bào)銷申請(qǐng)對(duì)象然后再將這個(gè)報(bào)銷申請(qǐng)對(duì)象存到數(shù)據(jù)庫(kù)當(dāng)中。那么這個(gè)代碼是這樣的:

          package com.jbpm.test;
          import junit.framework.TestCase;
          import org.hibernate.Session;
          public class TestJbpm_03 extends TestCase {
           
           
          public void testJbpm(){
            Session session 
          = null;
            
          try{
             session 
          = HibernateUtil.getSession();
             session.beginTransaction();
             
             Document doc 
          = new Document();
             doc.setTitle(
          "title3");
             doc.setContent(
          "this is content3");
             session.save(doc);      
             session.getTransaction().commit();
            }
          catch(Exception e){
             e.printStackTrace();
             session.getTransaction().rollback();
            }
          finally{
             HibernateUtil.closeSession(session);
            }
           }
          }

          package com.jbpm.test;
          import junit.framework.TestCase;
          import org.jbpm.JbpmConfiguration;
          import org.jbpm.JbpmContext;
          import org.jbpm.graph.def.ProcessDefinition;
          import org.jbpm.graph.exe.ProcessInstance;
          /**
          /*
          /*將申請(qǐng)單和流程實(shí)例綁定
          *
          */

          public class TestJbpm_04 extends TestCase {
           
           
          static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
           
           
          public void testJbpm(){
            
            JbpmContext jbpmContext 
          = jbpmConfiguration.createJbpmContext();
            jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());
            
          try {
             ProcessDefinition processDefinition 
          = jbpmContext.getGraphSession().findLatestProcessDefinition("testJbpm");
             ProcessInstance processInstance 
          = new ProcessInstance(processDefinition);
             jbpmContext.save(processInstance);  
             
             
             
          //將我們的document和instance綁定。
             long processInstanceId = processInstance.getId();
             Document document 
          = (Document)jbpmContext.getSession().load(Document.class,1);
             document.setProcessInstanceId(processInstanceId);
             jbpmContext.getSession().update(document);
             processInstance.getContextInstance().setVariable(
          "document", document.getId());
            }
          catch(Exception e){
             e.printStackTrace();
            }
          finally{
             jbpmContext.close();
            }
            
           }
          }

          現(xiàn)在我們的申請(qǐng)已經(jīng)和實(shí)例關(guān)聯(lián)起來(lái)了,那么接下來(lái)的下一步就開始用啦,就是讓 這個(gè)申請(qǐng)流轉(zhuǎn)起來(lái)吧,那么她應(yīng)該怎么去流轉(zhuǎn)呢,嘿嘿,jbpm給我們提供一個(gè)signal方法,每當(dāng)執(zhí)行一次這個(gè)方法的時(shí)候她就流轉(zhuǎn)一下到下一個(gè)節(jié)點(diǎn),你 可以打印出當(dāng)前節(jié)點(diǎn)試一下,看看是不是執(zhí)行一次你的當(dāng)前節(jié)點(diǎn)就換一下。這段代碼是這樣的:

          package com.jbpm.test;
          import junit.framework.TestCase;
          import org.jbpm.JbpmConfiguration;
          import org.jbpm.JbpmContext;
          import org.jbpm.graph.exe.ProcessInstance;
          public class TestJbpm_05 extends TestCase {
           
           
          static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
           
           
          public void testJbpm(){
            JbpmContext jbpmContext 
          = jbpmConfiguration.createJbpmContext();
            jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());
            
          try{
             
             Document document 
          = (Document)jbpmContext.getSession().load(Document.class3);
             
          long processInstanceId = document.getProcessInstanceId();
             ProcessInstance processInstance 
          = jbpmContext.getProcessInstance(processInstanceId);
             processInstance.signal();
            }
          finally{
             jbpmContext.close();
            }
           }
          }

          posted on 2009-03-03 14:27 龍櫻 閱讀(4165) 評(píng)論(3)  編輯  收藏 所屬分類: 非主流技術(shù)類

          評(píng)論

          # re: 【增】JBOSS 工作流與JBPM開發(fā)實(shí)例 2009-08-27 16:36 gusl.carnation@gmial.com

          最關(guān)鍵的,你這個(gè)流程能跑起來(lái)的前提是要有個(gè)數(shù)據(jù)庫(kù)支持,不然你的參與者怎么登陸進(jìn)去參與?  回復(fù)  更多評(píng)論   

          # re: 【增】JBOSS 工作流與JBPM開發(fā)實(shí)例 2009-09-07 12:48 傀儡

          當(dāng)然嘍,上面只是對(duì)JBPM的基礎(chǔ)配置與使用方法的講解,整合到SSH項(xiàng)目中就會(huì)視不同的DB而定了。但是總體JBPM34張表一定會(huì)導(dǎo)入的,這個(gè)是JBPM使用的核心,在JBPM開源文檔中對(duì)DB的移植做了全面的闡述,我這里就不班門弄斧了,有興趣的朋友可以下載源文件看一下。不知道這個(gè)回復(fù)您是否滿意。@gusl.carnation@gmial.com
            回復(fù)  更多評(píng)論   

          # re: 【增】JBOSS 工作流與JBPM開發(fā)實(shí)例 2010-05-22 00:02 ss

          確實(shí)不錯(cuò),但是感覺代碼邏輯不太好  回復(fù)  更多評(píng)論   

          <2009年9月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆分類(13)

          隨筆檔案(13)

          文章分類(1)

          文章檔案(1)

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 和政县| 东丽区| 新化县| 贵德县| 黑龙江省| 赤水市| 政和县| 井研县| 三门县| 都昌县| 西平县| 湾仔区| 湖州市| 丰顺县| 札达县| 靖边县| 昌江| 景泰县| 元氏县| 新晃| 松潘县| 株洲县| 浦江县| 拉孜县| 黔西| 沈丘县| 伊宁县| 蓝田县| 邵阳县| 河西区| 酒泉市| 五台县| 诏安县| 神农架林区| 灌阳县| 通海县| 玉门市| 榆林市| 罗江县| 祁东县| 金溪县|