jbpm 与 工作流模式 基本控制模式(一)

本文通过示例详细解析了JBPM中基本控制模式的工作流模式,包括顺序(sequence)、并行分支(Parallel Split)及同步聚合(Synchronization),并通过Java代码和XML配置展示了这些模式的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     工作流模式

     本文以jdpl/jar/src/test/java   jbpm3 关于workflow patterns 说明 jbpm 对 workflow patterns 的实现示例.

    基本控制模式 (Basic Control Flow Patterns)

    顺序 (sequence)
    Description :     An activity in a workow process is enabled after the completion of another
                            activity in the same process.
    描述:            :    同一个流程中, 一个活动在其他活动完成以后才能发生. 

   同义词        :       Sequential routing, serial routing.
    
   
java 代码
 
  1. /* 
  2.  * JBoss, Home of Professional Open Source 
  3.  * Copyright 2005, JBoss Inc., and individual contributors as indicated 
  4.  * by the @authors tag. See the copyright.txt in the distribution for a 
  5.  * full listing of individual contributors. 
  6.  * 
  7.  * This is free software; you can redistribute it and/or modify it 
  8.  * under the terms of the GNU Lesser General Public License as 
  9.  * published by the Free Software Foundation; either version 2.1 of 
  10.  * the License, or (at your option) any later version. 
  11.  * 
  12.  * This software is distributed in the hope that it will be useful, 
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
  15.  * Lesser General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public 
  18.  * License along with this software; if not, write to the Free 
  19.  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
  20.  * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 
  21.  */  
  22. package org.jbpm.jpdl.patterns;  
  23.   
  24. import junit.framework.TestCase;  
  25.   
  26. import org.jbpm.graph.def.ProcessDefinition;  
  27. import org.jbpm.graph.exe.ProcessInstance;  
  28. import org.jbpm.graph.exe.Token;  
  29.   
  30. /** 
  31.  * http://is.tm.tue.nl/research/patterns/download/swf/pat_1.swf 
  32.  */  
  33. public class Wfp01SequenceTest extends TestCase {  
  34.   
  35.   public void testSequence() {  
  36.     // create a simple definition with 3 states in sequence  
  37.     ProcessDefinition pd = ProcessDefinition.parseXmlString(  
  38.       " <process-definition>"</process-definition>  +  
  39.       "   +  
  40.       "     +  
  41.       "  " +  
  42.       "   +  
  43.       "     +  
  44.       "  " +  
  45.       "   +  
  46.       "     +  
  47.       "  " +  
  48.       "   +  
  49.       "     +  
  50.       "  " +  
  51.       "   +  
  52.       ""  
  53.     );  
  54.   
  55.     ProcessInstance pi = new ProcessInstance( pd );  
  56.     pi.signal();  
  57.     Token token = pi.getRootToken();  
  58.     assertSame( pd.getNode("a"), token.getNode() );  
  59.       
  60.     token.signal();  
  61.     assertSame( pd.getNode("b"), token.getNode() );  
  62.   
  63.     token.signal();  
  64.     assertSame( pd.getNode("c"), token.getNode() );  
  65.   
  66.     token.signal();  
  67.     assertSame( pd.getNode("end"), token.getNode() );  
  68.   }  
  69. }  
 
        <process-definition><start-state name="start"><state name="a"><state name="b"><state name="c">流程定义文件如下

     </state></state></state></start-state></process-definition>
xml 代码
  1. <process-definition>  
  2.     <start-state name='start'>  
  3.         <transition to='a' />  
  4.     start-state>  
  5.     <state name='a'>  
  6.         <transition to='b' />  
  7.     state>  
  8.     <state name='b'>  
  9.         <transition to='c' />  
  10.     state>  
  11.     <state name='c'>  
  12.         <transition to='end' />  
  13.     state>  
  14.     <end-state name='end' />  
  15. process-definition>
   节点流程      start --> a --> b --> c --> end
    <process-definition><start-state name="start"><state name="a"><state name="b"><state name="c">
        本例中包括start , a , b ,c ,end 四个node.  token.signal() 可以理解为流程中当前节点(token对应节点) 活动结束. 代码一目了然. 不需要过多解释.
   
    


  并行分支(Parallet Split) 


Description :    A point in the workow process where a single thread of control splits into multiple threads of control which can be executed in parallel, thus allowing activities to be executed simultaneously or in any order.

描述            :     在分支点上,一个工作流程执行线程 分出多个执行线程同时并行执行, 多个分支线程可以同时以任意顺序执行.

同义词:            AND-split, parallel routing, fork.

</state></state></state></start-state></process-definition>
java 代码
  1. /* 
  2.  * JBoss, Home of Professional Open Source 
  3.  * Copyright 2005, JBoss Inc., and individual contributors as indicated 
  4.  * by the @authors tag. See the copyright.txt in the distribution for a 
  5.  * full listing of individual contributors. 
  6.  * 
  7.  * This is free software; you can redistribute it and/or modify it 
  8.  * under the terms of the GNU Lesser General Public License as 
  9.  * published by the Free Software Foundation; either version 2.1 of 
  10.  * the License, or (at your option) any later version. 
  11.  * 
  12.  * This software is distributed in the hope that it will be useful, 
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
  15.  * Lesser General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public 
  18.  * License along with this software; if not, write to the Free 
  19.  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
  20.  * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 
  21.  */  
  22. package org.jbpm.jpdl.patterns;  
  23.   
  24. import junit.framework.TestCase;  
  25.   
  26. import org.jbpm.graph.def.ProcessDefinition;  
  27. import org.jbpm.graph.exe.ProcessInstance;  
  28. import org.jbpm.graph.exe.Token;  
  29.   
  30. /** 
  31.  * http://is.tm.tue.nl/research/patterns/download/swf/pat_2.swf 
  32.  */  
  33. public class Wfp02ParallelSplitTest extends TestCase {  
  34.   
  35.   public void testParallelSplit() {  
  36.     ProcessDefinition pd = ProcessDefinition.parseXmlString(  
  37.       " <process-definition>"</process-definition>  +  
  38.       "   +  
  39.       "     +  
  40.       "  " +  
  41.       "   +  
  42.       "     +  
  43.       "     +  
  44.       "  " +  
  45.       "   +  
  46.       "   +  
  47.       ""  
  48.     );  
  49.   
  50.     ProcessInstance pi = new ProcessInstance( pd );  
  51.     pi.signal();  
  52.     Token root = pi.getRootToken();  
  53.     assertNotNull( root );  
  54.       
  55.     Token firstToken = root.getChild( "first" );  
  56.     assertNotNull( firstToken );  
  57.     assertSame( pd.getNode("a"), firstToken.getNode() );  
  58.       
  59.     Token secondToken = root.getChild( "second" );  
  60.     assertNotNull( secondToken );  
  61.     assertSame( pd.getNode("b"), secondToken.getNode() );  
  62.   }  
  63. }  


流程定义文件:

xml 代码
  1. <process-definition>  
  2.     <start-state name='start'>  
  3.         <transition to='and' />  
  4.     start-state>  
  5.     <fork name='and'>  
  6.         <transition name='first' to='a' />  
  7.         <transition name='second' to='b' />  
  8.     fork>  
  9.     <state name='a' />  
  10.     <state name='b' />  
  11. process-definition>"  

         节点流程      start --> and -->  a
                                                     -- >  b

        本例中and --a   , and --> b  一定回被执行. 所以判断如下
         Token firstToken = root.getChild( "first" );
          assertNotNull( firstToken );

        并行分支 (AND-Split ) 多以 同步聚合((Synchronization)  结束.

同步聚合(Synchronization)

Description  : A point in the workow process where multiple parallel subprocesses/activities converge into one single thread of control, thus synchronizing multiple threads. It is an assumption of this pattern that each incoming branch of a synchronizer is executed only once

描述:            一个汇聚点, 多路工作流成执行线程汇聚成单个工作流执行线程. 只有汇聚线程都执行完毕,改汇聚点聚合后的单一线程才会执行.       

同义词:      AND-join, rendezvous, synchronizer.


java 代码
 
  1. /* 
  2.  * JBoss, Home of Professional Open Source 
  3.  * Copyright 2005, JBoss Inc., and individual contributors as indicated 
  4.  * by the @authors tag. See the copyright.txt in the distribution for a 
  5.  * full listing of individual contributors. 
  6.  * 
  7.  * This is free software; you can redistribute it and/or modify it 
  8.  * under the terms of the GNU Lesser General Public License as 
  9.  * published by the Free Software Foundation; either version 2.1 of 
  10.  * the License, or (at your option) any later version. 
  11.  * 
  12.  * This software is distributed in the hope that it will be useful, 
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
  15.  * Lesser General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public 
  18.  * License along with this software; if not, write to the Free 
  19.  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
  20.  * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 
  21.  */  
  22. package org.jbpm.jpdl.patterns;  
  23.   
  24. import junit.framework.*;  
  25.   
  26. import org.jbpm.graph.def.*;  
  27. import org.jbpm.graph.exe.*;  
  28.   
  29. /** 
  30.  * http://is.tm.tue.nl/research/patterns/download/swf/pat_3.swf 
  31.  */  
  32. public class Wfp03SynchronizationTest extends TestCase {  
  33.   
  34.   public ProcessDefinition createSynchronizationProcessDefinition() {  
  35.     ProcessDefinition pd = ProcessDefinition.parseXmlString(  
  36.       " <process-definition>"</process-definition>  +  
  37.       "   +  
  38.       "     +  
  39.       "  " +  
  40.       "   +  
  41.       "     +  
  42.       "     +  
  43.       "  " +  
  44.       "   +  
  45.       "     +  
  46.       "  " +  
  47.       "   +  
  48.       "     +  
  49.       "  " +  
  50.       "   +  
  51.       "     +  
  52.       "  " +  
  53.       "   +  
  54.       ""  
  55.     );  
  56.     return pd;  
  57.   }  
  58.   
  59.   public void testSynchronizationFirstTokenFirst() {  
  60.     ProcessDefinition pd = createSynchronizationProcessDefinition();  
  61.             
  62.     ProcessInstance pi = new ProcessInstance( pd );  
  63.     pi.signal();  
  64.     Token root = pi.getRootToken();  
  65.     Token firstToken = root.getChild( "first" );  
  66.     Token secondToken = root.getChild( "second" );  
  67.   
  68.     // check that the two tokens are in the states one and two respectively  
  69.     assertSame( pd.getNode("fork"), root.getNode() );  
  70.     assertSame( pd.getNode("one"), firstToken.getNode() );  
  71.     assertSame( pd.getNode("two"), secondToken.getNode() );  
  72.   
  73.     firstToken.signal();  
  74.     assertSame( pd.getNode("fork"), root.getNode() );  
  75.     assertSame( pd.getNode("join"), firstToken.getNode() );  
  76.     assertSame( pd.getNode("two"), secondToken.getNode() );  
  77.       
  78.     secondToken.signal();  
  79.     assertSame( pd.getNode("end"), root.getNode() );  
  80.     assertSame( pd.getNode("join"), firstToken.getNode() );  
  81.     assertSame( pd.getNode("join"), secondToken.getNode() );  
  82.   }  
  83.   
  84.   /** 
  85.    * variation of the pattern where the second token fires first. 
  86.    */  
  87.   public void testSynchronizationSecondTokenFirst() {  
  88.     ProcessDefinition pd = createSynchronizationProcessDefinition();  
  89.             
  90.     ProcessInstance pi = new ProcessInstance( pd );  
  91.     pi.signal();  
  92.     Token root = pi.getRootToken();  
  93.     Token firstToken = root.getChild( "first" );  
  94.     Token secondToken = root.getChild( "second" );  
  95.   
  96.     // check that the two tokens are in the states one and two respectively  
  97.     assertSame( pd.getNode("fork"), root.getNode() );  
  98.     assertSame( pd.getNode("one"), firstToken.getNode() );  
  99.     assertSame( pd.getNode("two"), secondToken.getNode() );  
  100.   
  101.     secondToken.signal();  
  102.     assertSame( pd.getNode("fork"), root.getNode() );  
  103.     assertSame( pd.getNode("one"), firstToken.getNode() );  
  104.     assertSame( pd.getNode("join"), secondToken.getNode() );  
  105.       
  106.     firstToken.signal();  
  107.     assertSame( pd.getNode("end"), root.getNode() );  
  108.     assertSame( pd.getNode("join"), firstToken.getNode() );  
  109.     assertSame( pd.getNode("join"), secondToken.getNode() );  
  110.   }  
  111.   
  112.   /** 
  113.    * nested form of the synchronization pattern. 
  114.    */  
  115.   public ProcessDefinition createNestedSynchronizationProcessDefinition() {  
  116.     // tip : draw this visually if you want to understand it.  
  117.     ProcessDefinition pd = new ProcessDefinition(  
  118.       new String[]{"start-state start",  
  119.                    "fork fork",  
  120.                    "fork fork1",  
  121.                    "fork fork2",  
  122.                    "state state1.1",  
  123.                    "state state1.2",  
  124.                    "state state2.1",  
  125.                    "state state2.2",  
  126.                    "join join2",  
  127.                    "join join1",  
  128.                    "join join",  
  129.                    "end-state end"},   
  130.       new String[]{"start --> fork",  
  131.                    "fork --first--> fork1",  
  132.                    "fork --second--> fork2",  
  133.                    "fork1 --first--> state1.1",  
  134.                    "fork1 --second--> state1.2",  
  135.                    "fork2 --first--> state2.1",  
  136.                    "fork2 --second--> state2.2",  
  137.                    "state1.1 --> join1",  
  138.                    "state1.2 --> join1",  
  139.                    "state2.1 --> join2",  
  140.                    "state2.2 --> join2",  
  141.                    "join1 --> join",  
  142.                    "join2 --> join",  
  143.                    "join --> end"});  
  144.     return pd;  
  145.   }  
  146.   
  147.   public void testSynchronizationNested() {  
  148.     ProcessDefinition pd = createNestedSynchronizationProcessDefinition();  
  149.     ProcessInstance pi = new ProcessInstance( pd );  
  150.     pi.signal();  
  151.     Token rootToken = pi.getRootToken();  
  152.     Token token1 = rootToken.getChild( "first" );  
  153.     Token token2 = rootToken.getChild( "second" );  
  154.     Token token11 = token1.getChild( "first" );  
  155.     Token token12 = token1.getChild( "second" );  
  156.     Token token21 = token2.getChild( "first" );  
  157.     Token token22 = token2.getChild( "second" );  
  158.       
  159.     assertSame( pd.getNode("fork"), rootToken.getNode() );  
  160.     assertSame( pd.getNode("fork1"), token1.getNode() );  
  161.     assertSame( pd.getNode("fork2"), token2.getNode() );  
  162.     assertSame( pd.getNode("state1.1"), token11.getNode() );  
  163.     assertSame( pd.getNode("state1.2"), token12.getNode() );  
  164.     assertSame( pd.getNode("state2.1"), token21.getNode() );  
  165.     assertSame( pd.getNode("state2.2"), token22.getNode() );  
  166.       
  167.     token11.signal();  
  168.   
  169.     assertSame( pd.getNode("fork"), rootToken.getNode() );  
  170.     assertSame( pd.getNode("fork1"), token1.getNode() );  
  171.     assertSame( pd.getNode("fork2"), token2.getNode() );  
  172.     assertSame( pd.getNode("join1"), token11.getNode() );  
  173.     assertSame( pd.getNode("state1.2"), token12.getNode() );  
  174.     assertSame( pd.getNode("state2.1"), token21.getNode() );  
  175.     assertSame( pd.getNode("state2.2"), token22.getNode() );  
  176.   
  177.     token12.signal();  
  178.   
  179.     assertSame( pd.getNode("fork"), rootToken.getNode() );  
  180.     assertSame( pd.getNode("join"), token1.getNode() );  
  181.     assertSame( pd.getNode("fork2"), token2.getNode() );  
  182.     assertSame( pd.getNode("join1"), token11.getNode() );  
  183.     assertSame( pd.getNode("join1"), token12.getNode() );  
  184.     assertSame( pd.getNode("state2.1"), token21.getNode() );  
  185.     assertSame( pd.getNode("state2.2"), token22.getNode() );  
  186.   
  187.     token21.signal();  
  188.   
  189.     assertSame( pd.getNode("fork"), rootToken.getNode() );  
  190.     assertSame( pd.getNode("join"), token1.getNode() );  
  191.     assertSame( pd.getNode("fork2"), token2.getNode() );  
  192.     assertSame( pd.getNode("join1"), token11.getNode() );  
  193.     assertSame( pd.getNode("join1"), token12.getNode() );  
  194.     assertSame( pd.getNode("join2"), token21.getNode() );  
  195.     assertSame( pd.getNode("state2.2"), token22.getNode() );  
  196.   
  197.     token22.signal();  
  198.   
  199.     assertSame( pd.getNode("end"), rootToken.getNode() );  
  200.     assertSame( pd.getNode("join"), token1.getNode() );  
  201.     assertSame( pd.getNode("join"), token2.getNode() );  
  202.     assertSame( pd.getNode("join1"), token11.getNode() );  
  203.     assertSame( pd.getNode("join1"), token12.getNode() );  
  204.     assertSame( pd.getNode("join2"), token21.getNode() );  
  205.     assertSame( pd.getNode("join2"), token22.getNode() );  
  206.   }  
  207. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值