溫馨提示:您的每一次轉(zhuǎn)載,體現(xiàn)了我寫此文的意義!!!煩請(qǐng)您在轉(zhuǎn)載時(shí)注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          雪山飛鵠

          溫馨提示:您的每一次轉(zhuǎn)載,體現(xiàn)了我寫此文的意義!!!煩請(qǐng)您在轉(zhuǎn)載時(shí)注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            215 Posts :: 1 Stories :: 674 Comments :: 0 Trackbacks

          最近開(kāi)始接觸JBPM4,網(wǎng)上關(guān)于JBPM4的資料少之又少。大多是關(guān)于JBPM3的。而4跟3的API差異也較大。在學(xué)習(xí)過(guò)程中做了一點(diǎn)關(guān)于JBPM4的筆記。強(qiáng)烈期望JBPM4達(dá)人能貢獻(xiàn)一些JBPM4方面的學(xué)習(xí)資料或視頻教程或出版發(fā)行JBPM4的書(shū)籍之類的。
          本文電子版下載

          流程定義引擎:

          ProcessEngine processEngine;

          獲取:

          processEngine=Configuration.getProcessEngine();

          重要的幾個(gè)接口:

          RepositoryService repositoryService;

          ExecutionService executionService;

          TaskService taskService;

          HistoryService historyService;

          ManagementService managementService;

          獲取:

          repositoryService=processEngine.getRepositoryService();

          executionService=processEngine.getExecutionService();

          taskService=processEngine.getTaskService();

          historyService=processEngine.getHistoryService();

          managementService=processEngine.getManagementService();

          說(shuō)明:

          RepositoryService主要用來(lái)管理和發(fā)布流程定義,發(fā)布流程定義、刪除流程定義、查看流程定義。

          流程定義發(fā)布:

          repositoryService.createDeployment().addResourceFromClasspath("demo.jpdl.xml").deploy();

          :此方法表示從classpath路徑加載一個(gè)流程定義文件,并發(fā)布,上例中demo.jpdl.xml文件位于src(classpath)路徑下,若流程定義文件放置與包中,則需要使用包名+jpdl文件名。如com/jbpm/demo.jpdl.xml

          查看流程定義:

          repositoryService.createDeployment().addResourceFromClasspath("test1.jpdl.xml").deploy();

          List<ProcessDefinition> list=repositoryService.createProcessDefinitionQuery().list();

          for (ProcessDefinition processDefinition : list) {

             System.out.println("流程定義Id:"+processDefinition.getId());

             System.out.println("流程部署Id:"+processDefinition.getDeploymentId());

          }

          刪除流程定義:

          String deploymentId=repositoryService.createDeployment().addResourceFromClasspath("test1.jpdl.xml").deploy();

          repositoryService.deleteDeploymentCascade(deploymentId);

          deploymentId為流程定義部署Id

          ExecutionService主要用來(lái)操作流程實(shí)例,啟動(dòng)流程實(shí)例、查看流程實(shí)例、刪除流程實(shí)例、結(jié)束流程實(shí)例。

          其前提條件是發(fā)布了流程定義

          啟動(dòng)流程實(shí)例:

          repositoryService.createDeployment().addResourceFromClasspath("demo.jpdl.xml").deploy();

                ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

          使用executionService.startProcessInstanceByKey("demo");方法來(lái)啟動(dòng)一個(gè)流程實(shí)例。其中startProcessInstanceByKey就表示以key的方式來(lái)啟動(dòng)流程實(shí)例,key為流程定義文件中process節(jié)點(diǎn)的key屬性,若未明確給出key屬性,則默認(rèn)key屬性的值與name屬性的值相同。

          同樣也可以使用executionService.startProcessInstanceById(processDefinitionId)的方式來(lái)啟動(dòng)流程實(shí)例。此方法是用流程定義文件中process節(jié)點(diǎn)的id屬性來(lái)啟動(dòng)流程實(shí)例。

          Id屬性由兩部分組成流程定義的key和流程定義的版本來(lái)組成。形如key-version

          例如:

          ProcessInstance processInstance=executionService.startProcessInstanceById("demo-1");

          其中demo-1就為流程定義中的流程Id,其keydemo,版本號(hào)為1

          同樣使用此方法可用來(lái)啟動(dòng)指定版本號(hào)的流程實(shí)例。

          查看流程實(shí)例:

          List<ProcessInstance> list=executionService.createProcessInstanceQuery().list();

          for (ProcessInstance processInstance : list) {

             System.out.println("流程實(shí)例Id:"+processInstance.getId());

             System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());

          }

          級(jí)聯(lián)刪除流程實(shí)例:

          executionService.deleteProcessInstanceCascade(processInstance.getId());

          結(jié)束流程實(shí)例:

          executionService.endProcessInstance(processInstance.getId(), "結(jié)束流程實(shí)例");

          注意:在使用executionService.endProcessInstance()對(duì)流程實(shí)例進(jìn)行結(jié)束操作后,需要重新查詢processInstance才能得到更新后的流程實(shí)例,如果流程已結(jié)束,則查詢結(jié)果為null

          如:

          executionService.endProcessInstance(processInstance.getId(), "結(jié)束流程實(shí)例");

          System.out.println(processInstance.isEnded());

          此行代碼是無(wú)意義的,因?yàn)榇藭r(shí)并未獲取到更新后的流程實(shí)例,需要重新查詢流程實(shí)例,所以此處返回為false

          System.out.println("-----------查詢流程實(shí)例--------------->");

          List<ProcessInstance> list=executionService.createProcessInstanceQuery().list();

          for (ProcessInstance processInstance : list) {

             System.out.println("流程實(shí)例Id:"+processInstance.getId());

             System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());

          }

          結(jié)果:

          false

          -----------查詢流程實(shí)例--------------->

          使流程向下執(zhí)行:

          在使用executionService啟動(dòng)流程實(shí)例后,流程會(huì)順著向下執(zhí)行(即啟動(dòng)流程實(shí)例后,流程會(huì)從start節(jié)點(diǎn)向下移動(dòng)),statetask節(jié)點(diǎn),流程會(huì)暫停下來(lái),滿足條件后流程會(huì)向下繼續(xù)執(zhí)行,直到流程end節(jié)點(diǎn),結(jié)束流程。

          在程序中是流程遵循某一條件,沿著某個(gè)方向流動(dòng)的方法為executionService.signalExecutionById();

          該方法有多個(gè)重載:

          ProcessInstance signalExecutionById(String executionId);

          //若在流程定義某一個(gè)節(jié)點(diǎn)沒(méi)有分支時(shí)(只有一個(gè)transition時(shí)),調(diào)用此方法,可將流程繼續(xù)向下執(zhí)行 executionId為流程實(shí)例Id

          ProcessInstance signalExecutionById(String executionId, String signalName);

          //若在流程定義某一個(gè)節(jié)點(diǎn)有多個(gè)分支時(shí)(有多個(gè)transition時(shí)),調(diào)用此方法,可將流程沿著transition所指的方向向下執(zhí)行

          executionId為流程實(shí)例Id, signalName為流程定義中transition節(jié)點(diǎn)的name屬性的值

          ProcessInstance signalExecutionById(String executionId, String signalName, Map<String, ?> parameters);

          用于將流程沿著signalName方向(transitionname屬性所指的方向)向下繼續(xù)執(zhí)行,在執(zhí)行的過(guò)程中順便傳遞參數(shù)parameters

          ProcessInstance signalExecutionById(String executionId, Map<String, ?> parameters);

          用于將流程向下繼續(xù)執(zhí)行,在執(zhí)行的過(guò)程中順便傳遞參數(shù)parameters

          :當(dāng)一個(gè)節(jié)點(diǎn)有多個(gè)分支時(shí),若要通過(guò)signalExecutionById()方法將流程向下執(zhí)行必須明確指出signalName(transitionname屬性所指的方向),否則流程不會(huì)向下執(zhí)行,仍會(huì)停留在當(dāng)前節(jié)點(diǎn)。因?yàn)?/span>jbpm不確定流程該流向那個(gè)方向。

          示例代碼:

          1. 沒(méi)有分支的state流向

          流程定義文件:

          <?xmlversion="1.0"encoding="UTF-8"?>

          <processname="demo"xmlns="http://jbpm.org/4.3/jpdl">

             <startname="start"g="87,113,48,48">

                <transitionname="to state"to="state"g="-53,-17"/>

             </start>

             <statename="state"g="238,236,92,52">

                <transitionname="to end"to="end"g="-41,-17"/>

             </state>

             <endname="end"g="384,367,48,48"/>

          </process>

          測(cè)試代碼:

          import org.jbpm.api.Configuration;

          import org.jbpm.api.ExecutionService;

          import org.jbpm.api.ProcessEngine;

          import org.jbpm.api.ProcessInstance;

          import org.jbpm.api.RepositoryService;

          import junit.framework.TestCase;

          publicclass DemoTest extends TestCase{

             ProcessEngine processEngine;

             RepositoryService repositoryService;

             ExecutionService executionService;

             @Override

             protectedvoid setUp() throws Exception {

                processEngine=Configuration.getProcessEngine();

                repositoryService=processEngine.getRepositoryService();

                executionService=processEngine.getExecutionService();

                //部署流程定義

             repositoryService.createDeployment().addResourceFromClasspath("demo.jpdl.xml").deploy();

             }

             publicvoid testProcessInstance(){

                ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                System.out.println("流程實(shí)例Id:"+processInstance.getId());

                System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());

                //判斷當(dāng)前是否位于start節(jié)點(diǎn)

                System.out.println("是否位于start節(jié)點(diǎn):"+processInstance.isActive("start"));

                //判斷當(dāng)前是否位于state節(jié)點(diǎn)

                System.out.println("是否位于state節(jié)點(diǎn):"+processInstance.isActive("state"));

                //判斷流程是否結(jié)束

                System.out.println("判斷流程是否結(jié)束:"+processInstance.isEnded());

                System.out.println("------------------------>使流程繼續(xù)向下執(zhí)行");

                //使流程繼續(xù)向下執(zhí)行

                //ProcessInstance instanceState=executionService.signalExecutionById(processInstance.getId());

                //此處也可以這么寫

                ProcessInstance instanceState=executionService.signalExecutionById(processInstance.getId(),"to end");

                //to end為流程定義中用于連接stateend節(jié)點(diǎn)之間transitionname屬性的值

                //判斷當(dāng)前是否位于state節(jié)點(diǎn)

                System.out.println("是否位于state節(jié)點(diǎn):"+instanceState.isActive("state"));

                //判斷流程是否結(jié)束

                System.out.println("判斷流程是否結(jié)束:"+instanceState.isEnded());

             }

          }

          執(zhí)行結(jié)果:

          流程實(shí)例Id:demo1.7

          流程定義Id:demo1-1

          是否位于start節(jié)點(diǎn):false

          是否位于state節(jié)點(diǎn):true

          判斷流程是否結(jié)束:false

          ------------------------>使流程繼續(xù)向下執(zhí)行

          是否位于state節(jié)點(diǎn):false

          判斷流程是否結(jié)束:true

          2. 含有分支的state流向

          流程定義文件:

          <?xmlversion="1.0"encoding="UTF-8"?>

          <processname="demo"xmlns="http://jbpm.org/4.3/jpdl">

             <startg="347,27,48,48"name="start">

                <transitiong="-53,-17"name="to state"to="state"/>

             </start>

             <stateg="329,132,92,52"name="state">

                <transitionname="to 200"to="200"g="-41,-17"/>

                <transitionname="to 400"to="400"g="-41,-17"/>

             </state>

             <endg="358,321,48,48"name="end"/>

             <statename="200"g="420,226,92,52">

                <transitionname="to end"to="end"g="-41,-17"/>

             </state>

             <statename="400"g="266,225,92,52">

                <transitionname="to end"to="end"g="-41,-17"/>

             </state>

          </process>

          測(cè)試代碼:

          import junit.framework.TestCase;

          public class Demo2Test extends TestCase{

             ProcessEngine processEngine;

             RepositoryService repositoryService;

             ExecutionService executionService;

             @Override

             protected void setUp() throws Exception {

                processEngine=Configuration.getProcessEngine();

                repositoryService=processEngine.getRepositoryService();

                executionService=processEngine.getExecutionService();

                //部署流程定義

             repositoryService.createDeployment().addResourceFromClasspath("demo.jpdl.xml").deploy();

             }

             public void testProcessInstance(){

                ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                System.out.println("流程實(shí)例Id:"+processInstance.getId());

                System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());

                //判斷當(dāng)前是否位于start節(jié)點(diǎn)

                System.out.println("是否位于start節(jié)點(diǎn):"+processInstance.isActive("start"));

                //判斷當(dāng)前是否位于state節(jié)點(diǎn)

                System.out.println("是否位于state節(jié)點(diǎn):"+processInstance.isActive("state"));

                //判斷流程是否結(jié)束

                System.out.println("判斷流程是否結(jié)束:"+processInstance.isEnded());

                System.out.println("------------------------>使流程繼續(xù)向下執(zhí)行");

                //不明確指出流動(dòng)方向,看流程位于那個(gè)節(jié)點(diǎn)

                ProcessInstance instance=executionService.signalExecutionById(processInstance.getId());

                //判斷當(dāng)前是否位于state節(jié)點(diǎn)

                System.out.println("是否位于state節(jié)點(diǎn):"+instance.isActive("state"));

                //判斷流程是否結(jié)束

                System.out.println("判斷流程是否結(jié)束:"+instance.isEnded());

             }

          }

          執(zhí)行結(jié)果:

          流程實(shí)例Id:demo.7

          流程定義Id:demo-1

          是否位于start節(jié)點(diǎn):false

          是否位于state節(jié)點(diǎn):true

          判斷流程是否結(jié)束:false

          ------------------------>使流程繼續(xù)向下執(zhí)行

          是否位于state節(jié)點(diǎn):true

          判斷流程是否結(jié)束:false

          指明流向節(jié)點(diǎn):

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                System.out.println("------------------------>使流程繼續(xù)向下執(zhí)行");

                System.out.println("------------------------>使流程流向200");

                ProcessInstance processInstance200=executionService.signalExecutionById(processInstance.getId(), "to 200");

                System.out.println("當(dāng)前流程是否位于200節(jié)點(diǎn)---->"+processInstance200.isActive("200"));

                System.out.println("當(dāng)前流程是否結(jié)束---->"+processInstance200.isEnded());

                /*System.out.println("------------------------>使流程流向400");

                ProcessInstance processInstance400=executionService.signalExecutionById(processInstance.getId(), "to 400");

                System.out.println("當(dāng)前流程是否位于400節(jié)點(diǎn)---->"+processInstance400.isActive("400"));

                System.out.println("當(dāng)前流程是否結(jié)束---->"+processInstance400.isEnded());*/

          執(zhí)行效果:

          ------------------------>使流程繼續(xù)向下執(zhí)行

          ------------------------>使流程流向200

          當(dāng)前流程是否位于200節(jié)點(diǎn)---->true

          當(dāng)前流程是否結(jié)束---->false

          上述代碼中使用signalExecutionById()方法時(shí),傳入的是流程實(shí)例的Id,也可以使用以下代碼來(lái)完成同樣的工作:

          ProcessInstance processInstance=executionService.startProcessInstanceByKey("demo");

                //查詢?cè)摿鞒虒?shí)例的活動(dòng)節(jié)點(diǎn)

                System.out.println(processInstance.findActiveActivityNames());

                //因?yàn)榱鞒虒?shí)例啟動(dòng)后,它會(huì)自動(dòng)向下執(zhí)行,直到遇到statetask等節(jié)點(diǎn)時(shí)暫停下來(lái),在我們的流程定義文件中緊跟在start后的節(jié)點(diǎn)為state,所以流程實(shí)例會(huì)在state節(jié)點(diǎn)暫停下來(lái)

                Execution execution=processInstance.findActiveExecutionIn("state");

                ProcessInstance processInstance200=executionService.signalExecutionById(execution.getId(), "to 200");

                System.out.println("當(dāng)前流程是否位于200節(jié)點(diǎn)---->"+processInstance200.isActive("200"));

                System.out.println("當(dāng)前流程是否結(jié)束---->"+processInstance200.isEnded());

                //使流程繼續(xù)向下執(zhí)行(結(jié)束)

                System.out.println("-------使流程繼續(xù)向下執(zhí)行(結(jié)束)------->");

                ProcessInstance instance=executionService.signalExecutionById(processInstance200.getId());

                System.out.println("當(dāng)前流程是否結(jié)束---->"+instance.isEnded());

          執(zhí)行結(jié)果:

          [state]

          當(dāng)前流程是否位于200節(jié)點(diǎn)---->true

          當(dāng)前流程是否結(jié)束---->false

          -------使流程繼續(xù)向下執(zhí)行(結(jié)束)------->

          當(dāng)前流程是否結(jié)束---->true

          關(guān)于流程實(shí)例幾個(gè)重要的方法:

          processInstance.isEnded()判斷程實(shí)例是否結(jié)束結(jié)束返回true,否則返回false

          processInstance.isActive(“A”)判斷當(dāng)前流程是否處于A節(jié)點(diǎn)

          謹(jǐn)記executionService.signalExecutionById(String executionId, String signalName)方法中executionId為流程實(shí)例Id,signalName為流程向下執(zhí)行的transitionname屬性的值,而不是下一個(gè)節(jié)點(diǎn)的名稱。

          posted on 2010-09-28 16:44 雪山飛鵠 閱讀(4704) 評(píng)論(3)  編輯  收藏 所屬分類: jbpm4

          Feedback

          # re: 跟我一起學(xué)JBPM4之基礎(chǔ)概念 2010-09-28 20:11 臨遠(yuǎn)
          用戶手冊(cè):http://www.family168.com/tutorial/jbpm4.0/html/
          開(kāi)發(fā)指南:http://www.family168.com/tutorial/jbpm4devguide/html/index.html
          FAQ:http://www.family168.com/jbpm4/faq.html
          視頻:http://www.family168.com/jbpm4/video.html
          實(shí)例:http://xyz20003.javaeye.com/blog/679898  回復(fù)  更多評(píng)論
            

          # re: 跟我一起學(xué)JBPM4之基礎(chǔ)概念[未登錄](méi) 2010-09-29 00:33 大熊
          好貼是好貼,不過(guò)標(biāo)題是不是叫“jbpm4 核心api概覽“更準(zhǔn)確些  回復(fù)  更多評(píng)論
            

          # re: 跟我一起學(xué)JBPM4之基礎(chǔ)概念 2010-09-29 08:44 雪山飛鵠
          @臨遠(yuǎn)
          非常感謝臨遠(yuǎn)大哥,我第一次去family168的時(shí)候是學(xué)習(xí)ExtJs,那時(shí),也是國(guó)內(nèi)關(guān)于ExtJs的資料很少。而family168提供了很多關(guān)于ExtJs的資料。況且有出版書(shū),我也毫不猶豫的買了《深入淺出ExtJs》這本書(shū),正是這本書(shū)的到來(lái),才使得對(duì)ExtJs有很好的認(rèn)識(shí)。我也觀看了臨遠(yuǎn)大哥發(fā)布的JBPM4的視頻,感覺(jué)非常好。強(qiáng)烈期盼臨遠(yuǎn)大哥出版關(guān)于JBPM4的書(shū)籍,畢竟在國(guó)內(nèi),到目前為止JBPM4的書(shū)籍仍然空缺。相信能幫助更多熱衷于JBPM4的開(kāi)發(fā)者,書(shū)籍也會(huì)大賣。期盼中........
            回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 昌邑市| 承德县| 西峡县| 三河市| 治多县| 库尔勒市| 论坛| 榆林市| 屏山县| 台前县| 广元市| 长春市| 凤凰县| 绵阳市| 芦山县| 龙胜| 买车| 和顺县| 大同县| 洞头县| 南昌县| 农安县| 阿克苏市| 普兰县| 彰化市| 华坪县| 芦山县| 龙井市| 红桥区| 邵阳县| 安吉县| 永顺县| 游戏| 勃利县| 青川县| 黄陵县| 鄂伦春自治旗| 普定县| 古浪县| 通化市| 泰兴市|