精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

jBPM 3.2用戶指南 Hello World范例

開發(fā) 后端
本文節(jié)選自jBPM 3.2用戶指南的第三章。本節(jié)jBPM用戶指南提供了jBPM范例Hello World:一個(gè)數(shù)據(jù)庫范例,一個(gè)流程變量的context范例,一個(gè)任務(wù)分配范例,以及兩個(gè)定制action范例。

本教程向你展示用jpdl構(gòu)造的簡單流程和使用API管理流程運(yùn)行時(shí)執(zhí)行的過程。

本教程的形式是解釋一批范例。這些范例著眼于一個(gè)特定的主題并包含大量的注解。這些范例也能夠在jBPM下載軟件包的src/java.examples目錄中找到。

最好的學(xué)習(xí)方式是創(chuàng)建一個(gè)項(xiàng)目,并通過創(chuàng)建下面的范例的變體來體驗(yàn)它。

在開始之前,首先下載和安裝jBPM。

jBPM包含一個(gè)圖形設(shè)計(jì)器工具,可用于創(chuàng)建在這些范例中顯示的xml文件。你可以在《下載和安裝jBPM》部分找到下載這個(gè)圖形設(shè)計(jì)器的指南。你不需要為了完成本教程而使用這個(gè)圖形設(shè)計(jì)工具。

Hello World范例

流程定義是一個(gè)有向圖,由節(jié)點(diǎn)(node)和轉(zhuǎn)移(transition)組成。Hello world流程有三個(gè)節(jié)點(diǎn)。為了看到這些代碼片段如何組合在一起,我們從一個(gè)簡單的流程開始,不使用圖形設(shè)計(jì)工具。下面的圖顯示hello world流程的圖形表示:

圖 3.1. Hello world流程圖

Hello world流程圖

  1. public void testHelloWorldProcess() {  
  2. // 本方法顯示一個(gè)流程定義和此流程定義的執(zhí)行。這個(gè)流程定義有三個(gè)節(jié)點(diǎn):一個(gè)未命名的  
  3. // start狀態(tài),一個(gè)狀態(tài)s和一個(gè)名為end的結(jié)束狀態(tài)。  
  4. // 下面一行將一段xml文本解析為一個(gè)流程定義ProcessDefinition。流程定義是對(duì)流程  
  5. // 的正式描述,表示為一個(gè)Java對(duì)象。  
  6. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  7.     "<process-definition>" +  
  8.     "  <start-state>" +  
  9.     "    <transition to='s' />" +  
  10.     "  </start-state>" +  
  11.     "  <state name='s'>" +  
  12.     "    <transition to='end' />" +  
  13.     "  </state>" +  
  14.     "  <end-state name='end' />" +  
  15.     "</process-definition>" 
  16. );  
  17.  
  18.   // 下面一行代碼創(chuàng)建流程定義的一個(gè)執(zhí)行。流程執(zhí)行創(chuàng)建之后將擁有一個(gè)主執(zhí)行  
  19.   // 路徑(=根token),指向開始狀態(tài)節(jié)點(diǎn)。  
  20.   ProcessInstance processInstance = new ProcessInstance(processDefinition);  
  21.  
  22.   // 流程執(zhí)行創(chuàng)建之后,擁有一個(gè)主執(zhí)行路徑(=根token)。  
  23.   Token token = processInstance.getRootToken();  
  24.  
  25.   // 流程執(zhí)行創(chuàng)建之后,主執(zhí)行路徑指向流程定義的開始狀態(tài)節(jié)點(diǎn)。  
  26.   assertSame(processDefinition.getStartState(), token.getNode());  
  27.  
  28.   // 下面我們啟動(dòng)流程執(zhí)行,從缺省轉(zhuǎn)移路線離開開始狀態(tài)節(jié)點(diǎn)。  
  29.   token.signal();  
  30.   // signal方法將阻塞,直至流程執(zhí)行進(jìn)入一個(gè)等待狀態(tài)。  
  31.   // 流程執(zhí)行進(jìn)入了第一個(gè)等待狀態(tài):狀態(tài)s。所以主執(zhí)行路徑現(xiàn)在指向狀態(tài)s。  
  32.   assertSame(processDefinition.getNode("s"), token.getNode());  
  33.  
  34.   // 下面我們發(fā)送第二個(gè)信號(hào)。這將恢復(fù)流程執(zhí)行,通過缺省的轉(zhuǎn)移路徑離開狀態(tài)s。  
  35.   token.signal();  
  36.  
  37.   // 現(xiàn)在signal方法返回了,因?yàn)榱鞒虒?shí)例到達(dá)了結(jié)束狀態(tài)節(jié)點(diǎn)。  
  38.     assertSame(processDefinition.getNode("end"), token.getNode());  

數(shù)據(jù)庫范例

jBPM的一個(gè)基本特征是把處于等待狀態(tài)中的流程執(zhí)行持久化到數(shù)據(jù)庫中的能力。下面的范例將向你展示如何將一個(gè)流程實(shí)例保存到j(luò)BPM數(shù)據(jù)庫中。本范例也暗示存在一個(gè)流程執(zhí)行的上下文。下面各個(gè)方法在不同的用戶代碼片段中創(chuàng)建,例如,在web應(yīng)用程序中的一段用戶代碼發(fā)起一個(gè)流程執(zhí)行并將它持久化到數(shù)據(jù)庫中,隨后,一個(gè)消息驅(qū)動(dòng)bean從數(shù)據(jù)庫中裝載這個(gè)流程實(shí)例并恢復(fù)其執(zhí)行。

  1. public class HelloWorldDbTest extends TestCase {  
  2.  
  3.   static JbpmConfiguration jbpmConfiguration = null;   
  4.  
  5.   static {  
  6.     // 像此處的范例配置文件能夠在'src/config.files'中找到。典型地配置信息存在  
  7.    // 于資源文件'jbpm.cfg.xml'中,但在這里我們直接傳遞一個(gè)XML字符串形式的配置信息。  
  8.  
  9.     // 首先我們創(chuàng)建一個(gè)JbpmConfiguration靜態(tài)對(duì)象。系統(tǒng)中的所有線程可以使用  
  10.     // 同一個(gè)JbpmConfiguration,因此我們可以安全地把它設(shè)定為靜態(tài)的。  
  11.     jbpmConfiguration = JbpmConfiguration.parseXmlString(  
  12.       "<jbpm-configuration>" +  
  13.  
  14.       // jbpm-context機(jī)制能夠從jbmp使用的環(huán)境服務(wù)中分離出jbpm核心引擎。  
  15.  
  16.       "  <jbpm-context>" +  
  17.       "    <service name='persistence' " +  
  18.       "             factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />" +   
  19.       "  </jbpm-context>" +  
  20.  
  21.       // 同樣地,jbpm使用的所有資源文件可以從jbpm.cfg.xml中引用。  
  22.  
  23.       "  <string name='resource.hibernate.cfg.xml' " +  
  24.       "          value='hibernate.cfg.xml' />" +  
  25.       "  <string name='resource.business.calendar' " +  
  26.       "          value='org/jbpm/calendar/jbpm.business.calendar.properties' />" +  
  27.       "  <string name='resource.default.modules' " +  
  28.       "          value='org/jbpm/graph/def/jbpm.default.modules.properties' />" +  
  29.       "  <string name='resource.converter' " +  
  30.       "          value='org/jbpm/db/hibernate/jbpm.converter.properties' />" +  
  31.       "  <string name='resource.action.types' " +  
  32.       "          value='org/jbpm/graph/action/action.types.xml' />" +  
  33.       "  <string name='resource.node.types' " +  
  34.       "          value='org/jbpm/graph/node/node.types.xml' />" +  
  35.       "  <string name='resource.varmapping' " +  
  36.       "          value='org/jbpm/context/exe/jbpm.varmapping.xml' />" +  
  37.       "</jbpm-configuration>" 
  38.     );  
  39.   }  
  40.  
  41.   public void setUp() {  
  42.     jbpmConfiguration.createSchema();  
  43.   }  
  44.  
  45.   public void tearDown() {  
  46.     jbpmConfiguration.dropSchema();  
  47.   }  
  48.  
  49.   public void testSimplePersistence() {  
  50.     // 在以下的三個(gè)方法調(diào)用之間,所有的數(shù)據(jù)通過數(shù)據(jù)庫傳遞。在這個(gè)單元測(cè)試中,  
  51.     // 這三個(gè)方法是順序執(zhí)行的,因?yàn)槲覀円獪y(cè)試一個(gè)完整的流程場(chǎng)景。但是在現(xiàn)實(shí)  
  52.     //中,這些方法代表對(duì)服務(wù)器的不同請(qǐng)求。  
  53.  
  54.     // 因?yàn)槲覀儚囊粋€(gè)干凈的、空的內(nèi)存數(shù)據(jù)庫中啟動(dòng),必須首先部署流程?,F(xiàn)實(shí)中,  
  55.     // 流程部署是由流程開發(fā)者一次性完成的。  
  56.     deployProcessDefinition();  
  57.  
  58.     // 假設(shè)當(dāng)用戶在web應(yīng)用程序中提交一個(gè)form的時(shí)候,我們要啟動(dòng)一個(gè)流程實(shí)例……  
  59.     processInstanceIsCreatedWhenUserSubmitsWebappForm();  
  60.  
  61.     // 隨后,當(dāng)異步消息到達(dá)之后,將繼續(xù)執(zhí)行流程。  
  62.     theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();  
  63.   }  
  64.  
  65.   public void deployProcessDefinition() {  
  66.     // 本測(cè)試展示一個(gè)流程定義和該流程定義的一個(gè)執(zhí)行實(shí)例。這個(gè)流程定義有  
  67.     // 三個(gè)節(jié)點(diǎn):一個(gè)未命名的開始狀態(tài),一個(gè)狀態(tài)s和一個(gè)名為end的結(jié)束狀態(tài)。  
  68.     ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  69.       "<process-definition name='hello world'>" +  
  70.       "  <start-state name='start'>" +  
  71.       "    <transition to='s' />" +  
  72.       "  </start-state>" +  
  73.       "  <state name='s'>" +  
  74.       "    <transition to='end' />" +  
  75.       "  </state>" +  
  76.       "  <end-state name='end' />" +  
  77.       "</process-definition>" 
  78.     );  
  79.  
  80.     // 查找在上面的過程中已配置好的POJO持久化上下文生成器。  
  81.     JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  82.     try {  
  83.       // 將流程定義部署到數(shù)據(jù)庫。  
  84.       jbpmContext.deployProcessDefinition(processDefinition);  
  85.  
  86.     } finally {  
  87.       // 銷毀POJO持久化上下文。  
  88.      // 這包括刷新SQL,將流程定義插入到數(shù)據(jù)庫中。  
  89.       jbpmContext.close();  
  90.     }  
  91.   }  
  92.  
  93.   public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {  
  94.     // 本方法中的代碼應(yīng)存在于一個(gè)struts的action 或JSF托管的bean中。  
  95.  
  96.     //  查找在上面的過程中已配置好的POJO持久化上下文生成器。  
  97.     JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  98.     try {  
  99.  
  100.       GraphSession graphSession = jbpmContext.getGraphSession();  
  101.  
  102.       ProcessDefinition processDefinition =   
  103.           graphSession.findLatestProcessDefinition("hello world");  
  104.  
  105.       // 從數(shù)據(jù)庫中取得流程定義之后,我們可以創(chuàng)建該流程定義的一個(gè)執(zhí)行實(shí)例,  
  106.       // 就像Hello world范例中一樣(后者沒有使用持久化)。  
  107.       ProcessInstance processInstance =   
  108.           new ProcessInstance(processDefinition);  
  109.  
  110.       Token token = processInstance.getRootToken();   
  111.       assertEquals("start", token.getNode().getName());  
  112.       // 下面啟動(dòng)流程執(zhí)行  
  113.       token.signal();  
  114.       // 現(xiàn)在流程處于狀態(tài)s。  
  115.       assertEquals("s", token.getNode().getName());  
  116.  
  117.       // 現(xiàn)在流程實(shí)例被保存到數(shù)據(jù)庫中,所以流程執(zhí)行的當(dāng)前狀態(tài)被保存到數(shù)據(jù)庫中了。  
  118.       jbpmContext.save(processInstance);  
  119.       // 下面的方法將從數(shù)據(jù)庫中取回流程實(shí)例,通過提供另一個(gè)外部信號(hào)恢復(fù)流程的執(zhí)行。  
  120.  
  121.     } finally {  
  122.       // 銷毀POJO持久化上下文。  
  123.       jbpmContext.close();  
  124.     }  
  125.   }  
  126.  
  127.   public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {  
  128.     // 本方法中的代碼可以是一個(gè)消息驅(qū)動(dòng)bean的內(nèi)容。  
  129.     //查找在上面的代碼中已經(jīng)配置好的POJO持久化上下文生成器  
  130.     JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  
  131.     try {  
  132.  
  133.       GraphSession graphSession = jbpmContext.getGraphSession();  
  134.       // 首先,我們需要從數(shù)據(jù)庫中取回流程實(shí)例。為了知道哪個(gè)流程實(shí)例是我們這里要使用的,  
  135.       // 有幾個(gè)可選方法。在這個(gè)簡單的測(cè)試案例中,最容易的方式是在整個(gè)流程實(shí)例列表中查  
  136.       // 找,這將僅僅返回一個(gè)結(jié)果。所以,讓我們獲取這個(gè)流程定義。  
  137.  
  138.       ProcessDefinition processDefinition =   
  139.           graphSession.findLatestProcessDefinition("hello world");  
  140.  
  141.       // 現(xiàn)在,我們查找這個(gè)流程定義中的所有流程實(shí)例。  
  142.       List processInstances =   
  143.           graphSession.findProcessInstances(processDefinition.getId());  
  144.  
  145.       // 因?yàn)槲覀冎?,在這個(gè)單元測(cè)試測(cè)環(huán)境中只存在一個(gè)執(zhí)行實(shí)例。在現(xiàn)實(shí)中,  
  146.       // processInstanceId要從到達(dá)的消息內(nèi)容中提取,或來自用戶的選擇。  
  147.       ProcessInstance processInstance =   
  148.           (ProcessInstance) processInstances.get(0);  
  149.  
  150.       // 現(xiàn)在我們可以繼續(xù)流程執(zhí)行了。記住流程實(shí)例將信號(hào)轉(zhuǎn)發(fā)給主執(zhí)行路徑(=根token)。  
  151.       processInstance.signal();  
  152.  
  153.       // 發(fā)出信號(hào)之后,我們知道流程執(zhí)行到達(dá)了結(jié)束狀態(tài)。  
  154.       assertTrue(processInstance.hasEnded());  
  155.  
  156.       // 現(xiàn)在我們可以將流程執(zhí)行的狀態(tài)更新到數(shù)據(jù)庫中  
  157.       jbpmContext.save(processInstance);  
  158.  
  159.     } finally {  
  160.       // 銷毀POJO持久化上下文。  
  161.       jbpmContext.close();  
  162.     }  
  163.   }  

#p#

上下文(context)范例:流程變量

流程變量包含流程執(zhí)行過程中的上下文信息。流程變量類似于java.util.Map,將變量名映射到值,值是java對(duì)象。流程變量作為流程實(shí)例的一部分被持久化。為了保持簡單,在此范例中我們僅僅展示與流程變量有關(guān)的API,不考慮持久化。

  1. // 這個(gè)范例同樣從Hello world流程開始。  
  2. // 這次甚至沒有修改。  
  3. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  4.   "<process-definition>" +  
  5.   "  <start-state>" +  
  6.   "    <transition to='s' />" +  
  7.   "  </start-state>" +  
  8.   "  <state name='s'>" +  
  9.   "    <transition to='end' />" +  
  10.   "  </state>" +  
  11.   "  <end-state name='end' />" +  
  12.   "</process-definition>" 
  13. );  
  14.  
  15. ProcessInstance processInstance =  
  16.   new ProcessInstance(processDefinition);  
  17.  
  18. // 從流程實(shí)例中取得上下文實(shí)例,以處理流程變量。  
  19. ContextInstance contextInstance =   
  20.   processInstance.getContextInstance();  
  21.  
  22. // 在流程離開開始狀態(tài)之前,我們準(zhǔn)備在流程實(shí)例的上下文中設(shè)置一些流程變量。  
  23. contextInstance.setVariable("amount"new Integer(500));  
  24. contextInstance.setVariable("reason""i met my deadline");  
  25.  
  26. // 從現(xiàn)在開始,這些變量關(guān)聯(lián)到這個(gè)流程實(shí)例了?,F(xiàn)在這些變量可以通過用戶代碼  
  27. // 使用在這里顯示的API來訪問了,但是,也可以在action和節(jié)點(diǎn)實(shí)現(xiàn)中訪問。流  
  28. // 程變量作為流程實(shí)例的一部分,也被存儲(chǔ)到數(shù)據(jù)庫中。  
  29.  
  30. processInstance.signal();  
  31.  
  32. // 流程變量可以通過contextInstance訪問。  
  33.  
  34. assertEquals(new Integer(500),   
  35.              contextInstance.getVariable("amount"));  
  36. assertEquals("i met my deadline",   
  37.              contextInstance.getVariable("reason")); 

任務(wù)分配范例

在下面的例子中我們展示如何將任務(wù)分配給用戶。因?yàn)閖BPM工作流引擎和組織機(jī)構(gòu)模型的分離,一個(gè)用于計(jì)算參與者(actor)的表達(dá)式語言總是太受限了。因此,你必須指定一個(gè) AssignmentHandler接口的實(shí)現(xiàn)類來包含計(jì)算任務(wù)的參與者的過程。

  1. public void testTaskAssignment() {  
  2.   // 下面的流程基于hello world流程。狀態(tài)節(jié)點(diǎn)被任務(wù)節(jié)點(diǎn)取代。任務(wù)節(jié)點(diǎn)是jPDL中  
  3.   // 的一種節(jié)點(diǎn),表示一個(gè)等待狀態(tài),并創(chuàng)建在流程繼續(xù)執(zhí)行之前必須完成的任務(wù)。  
  4.   ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  5.     "<process-definition name='the baby process'>" +  
  6.     "  <start-state>" +  
  7.     "    <transition name='baby cries' to='t' />" +  
  8.     "  </start-state>" +  
  9.     "  <task-node name='t'>" +  
  10.     "    <task name='change nappy'>" +  
  11.     "      <assignment class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler' />" +  
  12.     "    </task>" +  
  13.     "    <transition to='end' />" +  
  14.     "  </task-node>" +  
  15.     "  <end-state name='end' />" +  
  16.     "</process-definition>" 
  17.   );  
  18.  
  19.   // 創(chuàng)建流程定義的一個(gè)執(zhí)行實(shí)例。  
  20.   ProcessInstance processInstance =   
  21.       new ProcessInstance(processDefinition);  
  22.   Token token = processInstance.getRootToken();  
  23.  
  24.   // 下面開始流程執(zhí)行,從缺省轉(zhuǎn)換路徑離開開始狀態(tài)。  
  25.   token.signal();  
  26.   // signal方法將阻塞,直至流程執(zhí)行進(jìn)入一個(gè)等待狀態(tài)。在這里,就是任務(wù)節(jié)點(diǎn)t。  
  27.   assertSame(processDefinition.getNode("t"), token.getNode());  
  28.  
  29.   // 當(dāng)流程執(zhí)行到達(dá)任務(wù)節(jié)點(diǎn),一個(gè)'換尿布(change nappy)'任務(wù)將被創(chuàng)建,  
  30.   // NappyAssignmentHandler被調(diào)用以決定把這個(gè)任務(wù)分配給誰。  
  31.   // NappyAssignmentHandler返回'(爸爸)papa'。  
  32.  
  33.   // 在真實(shí)的環(huán)境中,任務(wù)通過org.jbpm.db.TaskMgmtSession類中的方法從數(shù)據(jù)  
  34.   // 庫中取得。因?yàn)槲覀儾幌朐诒痉独邪志没膹?fù)雜性,我們僅僅從流程實(shí)例中  
  35.   // 取出第一個(gè)任務(wù)實(shí)例(我們知道在這個(gè)測(cè)試場(chǎng)景中只有一個(gè)任務(wù)實(shí)例)。  
  36.   TaskInstance taskInstance = (TaskInstance)    
  37.       processInstance  
  38.         .getTaskMgmtInstance()  
  39.         .getTaskInstances()  
  40.         .iterator().next();  
  41.  
  42.   // 現(xiàn)在,我們檢測(cè)任務(wù)實(shí)例是否真正被指派給'papa'.  
  43.   assertEquals("papa", taskInstance.getActorId() );  
  44.  
  45.   // 現(xiàn)在我們假設(shè)爸爸已經(jīng)完成他的任務(wù),并把任務(wù)標(biāo)記為已完成。  
  46.   taskInstance.end();  
  47.  
  48.   // 因?yàn)檫@是最后(唯一)一個(gè)要完成的任務(wù),這個(gè)任務(wù)的完成出發(fā)了流程實(shí)例的繼續(xù)執(zhí)行。  
  49.   assertSame(processDefinition.getNode("end"), token.getNode());  

定制action范例

action是把你的客戶java代碼綁定到j(luò)BPM流程的一種機(jī)制。action能夠關(guān)聯(lián)到它自己的節(jié)點(diǎn)(如果它們?cè)诹鞒痰膱D形表示中是相關(guān)的的話)。action也能夠放置在事件(例如進(jìn)入轉(zhuǎn)換、離開節(jié)點(diǎn)、進(jìn)入節(jié)點(diǎn)等)之中。在這種情況下,action不是流程的圖形表示的一部分,但是,當(dāng)運(yùn)行時(shí)流程執(zhí)行觸發(fā)了這些事件的時(shí)候,這些action將被執(zhí)行。

  1. // MyActionHandler代表一個(gè)能夠在jBPM流程執(zhí)行過程中執(zhí)行某些用戶代碼的類。  
  2. public class MyActionHandler implements ActionHandler {  
  3.  
  4.   // 在每個(gè)test之前(在setUp方法中), isExecuted成員將被設(shè)置為false。  
  5.   public static boolean isExecuted = false;    
  6.  
  7.   // action將把 isExecuted設(shè)置為true,使得單元測(cè)試能夠顯示action在什么時(shí)候被執(zhí)行。  
  8.   public void execute(ExecutionContext executionContext) {  
  9.     isExecuted = true;  
  10.   }  

我們從在下面的范例中將要用到的action實(shí)現(xiàn):MyActionHandler開始。這個(gè)action處理器實(shí)現(xiàn)沒有做真正有用的工作,僅僅把布爾變量isExecuted設(shè)置為true。變量isExecuted是靜態(tài)的,所以能夠同時(shí)從action處理器內(nèi)部和要校驗(yàn)它的值的action中訪問。

  1. // 每個(gè)測(cè)試將在開始時(shí)設(shè)置MyActionHandler的靜態(tài)成員isExecuted為false。  
  2. public void setUp() {  
  3.   MyActionHandler.isExecuted = false;  

下面的例子顯示同樣的action,但是現(xiàn)在action被分別放在enter-node和leave-node事件之中。請(qǐng)注意與轉(zhuǎn)換只有一個(gè)事件不同,節(jié)點(diǎn)擁有多個(gè)事件類型,因此被放置到節(jié)點(diǎn)中的action應(yīng)該放在event元素之中。

  1. public void testTransitionAction() {  
  2.     // 下面的流程是hello world流程的一個(gè)變體。我們把一個(gè)action加入從狀態(tài)s到結(jié)束狀  
  3.     // 態(tài)的轉(zhuǎn)換之中。本測(cè)試的目的是顯示要把java代碼集成到j(luò)BPM流程中是多么容易。  
  4.     ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  5.       "<process-definition>" +  
  6.       "  <start-state>" +  
  7.       "    <transition to='s' />" +  
  8.       "  </start-state>" +  
  9.       "  <state name='s'>" +  
  10.       "    <transition to='end'>" +  
  11.       "      <action class='org.jbpm.tutorial.action.MyActionHandler' />" +  
  12.       "    </transition>" +  
  13.       "  </state>" +  
  14.       "  <end-state name='end' />" +  
  15.       "</process-definition>" 
  16.     );  
  17.  
  18.     // 啟動(dòng)流程定義的一個(gè)新的執(zhí)行實(shí)例。  
  19.     ProcessInstance processInstance =   
  20.       new ProcessInstance(processDefinition);  
  21.  
  22.     // 下一個(gè)信號(hào)將導(dǎo)致執(zhí)行離開開始狀態(tài),到達(dá)狀態(tài)s。  
  23.     processInstance.signal();  
  24.  
  25.     // 這里我們顯示 MyActionHandler還沒有被執(zhí)行。  
  26.     assertFalse(MyActionHandler.isExecuted);  
  27.     // ... 以及主執(zhí)行路徑指向狀態(tài)s  
  28.     assertSame(processDefinition.getNode("s"),   
  29.                processInstance.getRootToken().getNode());  
  30.  
  31.     // 下一個(gè)信號(hào)將觸發(fā)根token的執(zhí)行。該token將取得包含action的轉(zhuǎn)換,  
  32.     // 該action將在調(diào)用signal方法的過程中執(zhí)行。  
  33.     processInstance.signal();  
  34.  
  35.     // 這里我們可以看到在signal方法被調(diào)用的時(shí)候, MyActionHandler被執(zhí)行了。  
  36.     assertTrue(MyActionHandler.isExecuted);  
  37.   } 
  1. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(  
  2.   "<process-definition>" +  
  3.   "  <start-state>" +  
  4.   "    <transition to='s' />" +  
  5.   "  </start-state>" +  
  6.   "  <state name='s'>" +  
  7.   "    <event type='node-enter'>" +  
  8.   "      <action class='org.jbpm.tutorial.action.MyActionHandler' />" +  
  9.   "    </event>" +  
  10.   "    <event type='node-leave'>" +  
  11.   "      <action class='org.jbpm.tutorial.action.MyActionHandler' />" +  
  12.   "    </event>" +  
  13.   "    <transition to='end'/>" +  
  14.   "  </state>" +  
  15.   "  <end-state name='end' />" +  
  16.   "</process-definition>" 
  17. );  
  18.  
  19. ProcessInstance processInstance =   
  20.   new ProcessInstance(processDefinition);  
  21.  
  22. assertFalse(MyActionHandler.isExecuted);  
  23. // 下一個(gè)信號(hào)將導(dǎo)致流程執(zhí)行離開開始狀態(tài),進(jìn)入狀態(tài)s。因此狀態(tài)s被進(jìn)入,action被執(zhí)行。  
  24. processInstance.signal();  
  25. assertTrue(MyActionHandler.isExecuted);  
  26.  
  27. // 重置MyActionHandler.isExecuted。  
  28. MyActionHandler.isExecuted = false;  
  29.  
  30. // 下一個(gè)信號(hào)將觸發(fā)流程執(zhí)行離開狀態(tài)s,因此action將被再次執(zhí)行。  
  31. processInstance.signal();  
  32. // 瞧……  
  33. assertTrue(MyActionHandler.isExecuted); 

【編輯推薦】

  1. jBPM 3.2用戶指南 概覽
  2. jBPM 4.0.0用戶指南 安裝配置
  3. jBPM數(shù)據(jù)庫表說明:流程節(jié)點(diǎn)表
  4. jBPM 4.0.0.Beta2版本發(fā)布
  5. Equinox動(dòng)態(tài)化深入分析
責(zé)任編輯:yangsai 來源: 大雅之堂
相關(guān)推薦

2009-06-11 13:53:35

jBPM用戶指南

2011-12-05 15:44:45

Knockout

2009-06-11 13:43:21

jBPM用戶指南jBPM 4.0

2014-12-19 10:07:10

C

2017-11-23 17:45:46

Yii框架IntelYii框架深度剖析

2012-02-20 14:26:48

JavaPlay Framew

2009-08-11 10:32:23

什么是Groovy

2009-07-30 13:21:17

Scala入門Hello World

2023-09-04 07:30:03

Wasm匯編語言

2023-01-06 08:18:44

2011-06-08 14:39:06

Qt 教程

2009-09-16 17:15:19

OSGi Bundle

2021-11-26 08:22:01

Java動(dòng)態(tài)開發(fā)

2014-04-11 11:36:42

NDKAndroid開發(fā)終端

2009-08-14 16:54:19

C# Hello Wo

2024-04-11 13:13:27

2011-08-05 09:48:46

iPhone Interface

2023-05-23 08:01:10

Netty網(wǎng)絡(luò)通信

2015-10-27 09:47:11

2021-03-30 13:48:47

WebAssemblyWeb瀏覽器編程語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩欧美电影在线观看| 久草视频在线资源站| 爱情电影社保片一区| 国产欧美一区二区精品秋霞影院| 久久久久久久综合| 亚洲va国产va欧美va观看| 成人动漫视频在线观看免费| 国产精品7777| 妖精视频一区二区三区| 在线看国产一区| 男同互操gay射视频在线看| 一级片在线免费观看视频| 综合久久一区| 日韩精品中文字幕在线| 三级a三级三级三级a十八发禁止| 黄色在线观看网站| 国产精品中文字幕一区二区三区| 97视频国产在线| 影音先锋男人在线| 中文字幕日韩高清在线| 91成人网在线| 免费的一级黄色片| 国产h在线观看| 成+人+亚洲+综合天堂| 国产精品老牛影院在线观看 | 国产白丝精品91爽爽久久| 97久久精品人搡人人玩| ass极品国模人体欣赏| 成人直播在线观看| 欧美日韩一区在线| 熟女少妇在线视频播放| 蜜桃av在线免费观看| www.亚洲激情.com| 亚洲一区中文字幕| 国产九色91回来了| 亚洲影院在线| 欧美精品videossex88| 香蕉成人在线视频| 国产成人影院| 亚洲国产天堂久久综合网| 色综合五月婷婷| 影视一区二区三区| 欧美日韩亚洲成人| 欧美国产日韩激情| 丝袜美腿av在线| 国产精品久久久久久亚洲毛片| 精品国产中文字幕| 亚洲第一成年人网站| 精品在线观看视频| 国产精品视频白浆免费视频| 狠狠人妻久久久久久综合| 激情综合激情| 欧美精品一本久久男人的天堂| 长河落日免费高清观看| 国产一区二区三区不卡视频网站| 亚洲黄色在线看| 国产51自产区| 91夜夜蜜桃臀一区二区三区| 欧美一区二区三区白人| 午夜精品久久久久久久99热影院| 天堂久久午夜av| 色天天综合色天天久久| 欧美日韩在线不卡视频| 欧美xx视频| 一本久久a久久免费精品不卡| 激情综合在线观看| 最近在线中文字幕| 一本大道久久a久久综合| 中文字幕日本最新乱码视频| 一区二区三区电影大全| 色哟哟国产精品免费观看| 漂亮人妻被中出中文字幕| 亚洲精品中文字幕| 欧美性生活久久| 日本人69视频| 欧美一级大片在线视频| 日韩一二在线观看| 成年人小视频在线观看| 色天下一区二区三区| 亚洲精品小视频| 欧美 变态 另类 人妖| 国产精品手机在线播放| 中文字幕亚洲综合| 中文字幕无码日韩专区免费| 欧美福利视频| 国a精品视频大全| 精品免费囯产一区二区三区| 日韩国产在线一| 国产日韩精品在线| 午夜精品久久久久久久爽| www.欧美.com| 日本午夜精品一区二区三区| 69久久久久| 一区二区三区四区在线| 日本日本19xxxⅹhd乱影响| 电影亚洲精品噜噜在线观看| 欧美精品日韩一本| 人妻av一区二区| 成人嫩草影院| 欧美激情精品久久久| 精品人妻一区二区三区免费看 | 欧美网色网址| 亚洲最新在线视频| 麻豆疯狂做受xxxx高潮视频| 亚洲欧美久久久| 成人国产在线激情| 视频一区二区免费| 国产精品欧美一级免费| 东北少妇不带套对白| 成人高清一区| 亚洲精品一线二线三线无人区| 一区二区三区四区免费| 欧美96在线丨欧| 日韩美女视频免费看| av手机免费看| 国产日韩欧美在线一区| av一区二区三区免费观看| av在线日韩| 精品国产凹凸成av人导航| 国产又粗又猛又爽又黄的视频四季| 欧美日韩理论| 国产成人aa精品一区在线播放| www.久久精品.com| 欧美国产日韩亚洲一区| 草b视频在线观看| 日韩一级特黄| 一本色道久久88综合日韩精品| 国产真实乱偷精品视频| 精品一区二区三区的国产在线播放| 国产一区二区三区黄| av片在线观看网站| 欧美特级限制片免费在线观看| 性囗交免费视频观看| 永久91嫩草亚洲精品人人| 国产精品 欧美在线| 日韩中文字幕影院| 亚洲精品国产a久久久久久| 天天干天天草天天| 精品国产乱码久久久久久果冻传媒 | 男女在线视频| 欧美日本一区二区| 亚洲日本精品视频| 亚洲女同同性videoxma| 极品尤物一区二区三区| 大桥未久在线播放| 日韩欧美自拍偷拍| 男女性高潮免费网站| 蜜桃av一区二区三区| 日本亚洲欧洲精品| 亚洲黄色网址| 亚洲免费福利视频| 国产三级av片| 99精品视频在线观看| 国产黄色激情视频| 欧美成年网站| 九九热这里只有精品免费看| 精品国自产在线观看| 亚洲精品免费一二三区| 免费黄频在线观看| 中文乱码免费一区二区三区下载| 国产精品一区电影| av在线女优影院| 欧美日韩一级二级三级| 99热6这里只有精品| 六月婷婷色综合| 中文字幕在线中文字幕日亚韩一区| 欧美aaa级| 久久亚洲电影天堂| 亚洲高清精品视频| 五月婷婷激情综合| 蜜桃精品成人影片| 久久午夜电影| 亚洲午夜精品福利| 在线免费成人| 欧美高清视频在线| 无码国产精品一区二区免费16| 天天操天天色综合| av男人的天堂av| 蜜臀av性久久久久蜜臀aⅴ四虎| 香蕉久久夜色| 精品国产亚洲一区二区三区在线| 久久91亚洲人成电影网站| 男人天堂网在线视频| 日韩欧美成人网| 国产在线免费av| 国产精品一二三四五| 国产午夜福利100集发布| 美女久久久久| 国产日韩欧美电影在线观看| 视频在线这里都是精品| 亚洲精品国产成人| a片在线免费观看| 一区二区在线观看视频| 成人免费网站黄| 美女在线视频一区| 欧美大黑帍在线播放| 九九综合久久| 亚洲影院高清在线| av高清不卡| 欧美成年人视频网站欧美| 天天av综合网| 91精品国产全国免费观看| 西西44rtwww国产精品| 国产精品电影一区二区三区| 国产高潮失禁喷水爽到抽搐| 日韩高清在线不卡| 欧美乱做爰xxxⅹ久久久| sdde在线播放一区二区| 国产精品欧美久久| 日韩成人精品一区二区三区| 2025国产精品视频| 国产黄a三级三级三级av在线看| 日韩经典第一页| aaa级黄色片| 欧美亚一区二区| 日本一区二区三区精品| 一区二区三区在线视频观看 | 国产精品国产a| 国产精品久久久免费观看| 黑人巨大精品欧美一区| 日韩久久一级片| 国模吧视频一区| 在线视频不卡一区二区三区| 一本色道久久综合狠狠躁的番外| 亚洲一区免费网站| 国产一区二区三区四区五区3d | 色成人免费网站| 久久久爽爽爽美女图片| а√天堂在线官网| 少妇高潮 亚洲精品| 美国成人毛片| 日韩电影在线观看中文字幕 | 在线观看91视频| 国产精品男女视频| 亚洲成av人影院在线观看网| 国模无码国产精品视频| 国产精品久久久久久久久动漫| 无码人妻精品一区二区三区温州| 国产精品91一区二区| 色网站在线视频| 极品少妇xxxx精品少妇| 天堂网在线免费观看| 视频一区欧美日韩| 国产黄色特级片| 久久九九99| 免费观看精品视频| 久久精品国语| 欧美精品一区二区三区免费播放| 夜夜嗨一区二区三区| 毛片在线播放视频| 亚洲精品在线二区| 免费视频爱爱太爽了| 国产主播一区| 国产精品www在线观看| 亚洲高清在线| 黄色一级片在线看| 激情成人综合| 日韩欧美亚洲天堂| 久久精品五月| 天天干天天爽天天射| 奇米影视在线99精品| 岛国av在线免费| 精品一区二区三区视频在线观看| 亚洲午夜精品一区| 国产精品99久久久久久有的能看| 古装做爰无遮挡三级聊斋艳谭| 国产成人精品综合在线观看| 国产精品果冻传媒| 99久久精品免费看国产| 国产黄色网址在线观看| 欧美韩国一区二区| 日韩欧美123区| 亚洲国产另类av| 免费观看一区二区三区毛片| 日韩欧美中文字幕在线播放| 高潮毛片又色又爽免费| 欧美日韩卡一卡二| 国产福利视频导航| 亚洲国产精品人久久电影| 你懂的在线看| 精品国产一区二区三区久久狼黑人| a篇片在线观看网站| 韩日欧美一区二区| 99欧美精品| 99理论电影网| 你微笑时很美电视剧整集高清不卡| 日韩在线三级| 欧美精品啪啪| 国产一区亚洲二区三区| 久久99精品一区二区三区 | 午夜精品久久久久久毛片| av蓝导航精品导航| 精品中文字幕一区二区三区av| 这里只有精品66| 在线观看一区| 天堂一区在线观看| 成人综合婷婷国产精品久久免费| 国产精品成人一区二区三区电影毛片| 国产精品伦一区二区三级视频| 久久久久久天堂| 日本乱码高清不卡字幕| 国产99久一区二区三区a片 | 99青草视频在线播放视| 欧美国产亚洲视频| 日韩三区在线| 国产精品污www一区二区三区| 欧美色女视频| av在线播放亚洲| 久草在线在线精品观看| 欧美 变态 另类 人妖| 日韩美女久久久| 国产又粗又爽视频| 精品免费视频一区二区| www.av在线| 2019中文字幕在线| 激情不卡一区二区三区视频在线 | 日本三级黄色网址| 91在线丨porny丨国产| 中文字幕影音先锋| 欧美三级欧美一级| 人操人视频在线观看| 欧美激情视频一区| 不卡精品视频| 色一情一区二区三区四区| 亚洲精品少妇| 久久久久无码国产精品一区李宗瑞 | 欧美日韩xxx| 国产成人免费| 日本一区免费| 亚洲女同在线| 亚洲av成人片色在线观看高潮| 亚洲色图另类专区| 中文字幕免费在线看| 亚洲欧洲激情在线| 桃色av一区二区| 国产精品久久九九| 欧美黄色一区| 日韩精品aaa| 亚洲色图在线视频| 亚洲一级片免费看| 自拍亚洲一区欧美另类| 国产一区二区三区朝在线观看| 免费看成人av| 校园激情久久| 国精产品一区一区三区免费视频| 婷婷亚洲久悠悠色悠在线播放| 亚洲免费成人在线| 欧美日本精品在线| 日韩精品一区二区三区中文字幕 | 影院欧美亚洲| 国产吃瓜黑料一区二区| 亚洲激情第一区| 精品国产无码AV| 欧美黄色片免费观看| 91麻豆精品激情在线观看最新 | 韩国中文字幕在线| 91久久精品国产91性色| 亚洲深深色噜噜狠狠爱网站| 99久久99精品| 亚洲综合在线免费观看| 欧美少妇bbw| 2019中文字幕在线观看| 自拍自偷一区二区三区| 蜜臀视频一区二区三区| 中文字幕第一区二区| 国产精品毛片一区视频播| 欧美成人激情视频| av一级亚洲| 国模吧无码一区二区三区| 久久精品日韩一区二区三区| 艳妇乳肉豪妇荡乳av无码福利 | 国产一区二区高清视频| 久久av一区二区三区| 欧美人与性囗牲恔配| 欧美精品1区2区3区| 免费污视频在线| 精选一区二区三区四区五区| 天堂一区二区在线| 久久精品一区二区三区四区五区| 日韩精品一区二区三区视频| 欧美久久天堂| 亚洲一区美女| 大尺度一区二区| 亚洲另类在线观看| 久久亚洲精品一区二区| 久久久久97| 污视频免费在线观看网站| 亚洲精品视频在线观看免费| 日韩在线观看视频网站| 国产精品日韩在线| 黑丝一区二区三区| 久久亚洲AV无码专区成人国产| 51午夜精品国产| 美女搞黄视频在线观看| 亚洲国产一区二区三区在线播| 国产精品夜夜嗨| 日韩在线 中文字幕| 九九视频这里只有精品| 九九精品在线| 亚洲欧洲国产视频|