activiti学习资料(子流程subProcess)

Activiti 5.3:子流程(subProcess)


Activiti 5.3提供了子流程的实现,包括两种基于子流程的实现:

一种是内嵌子流程:子流程元素<subProcess>内嵌在主流程元素<process>之内,只能在该流程中使用该子流程,外部是无法访问到的。这种子流程一般作为局部通用逻辑处理,或者因为特定业务需要,使得比较复杂的单个主流程设计清晰直观;

另一种是调用子流程:首先实现一个流程,在另一个流程中可以调用该流程,通常可以定义一些通用的流程作为这种调用子流程,供其他多个流程定义复用。这种子流程使用<callActivity>元素来进行调用,间接地嵌入到主流程中,用起来比较方便。

 

内嵌子流程

实现的基于内嵌子流程的流程,示例如图所示:

activiti学习资料(子流程subProcess)_第1张图片 

对应的流程定义文件SubProcessTest.MySubprocess.bpmn20.xml,内容如下所示:

[java]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <definitions id="definitions"  
  3.     xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn"  
  4.     targetNamespace="Examples">  
  5.     <process id="MySubprocess" name="My Subprocess">  
  6.         <startEvent id="theStart" />  
  7.         <sequenceFlow id="flow1" sourceRef="theStart" targetRef="subProcess" />  
  8.           
  9.         <subProcess id="subProcess">  
  10.             <startEvent id="subProcessStart" />  
  11.             <sequenceFlow id="flow2" sourceRef="subProcessStart" targetRef="subProcessFork" />  
  12.             <parallelGateway id="subProcessFork" />  
  13.             <sequenceFlow id="flow3" sourceRef="subProcessFork" targetRef="task1" />  
  14.             <sequenceFlow id="flow4" sourceRef="subProcessFork" targetRef="task2" />  
  15.             <userTask id="task1" name="Check bank" activiti:candidateGroups="engineering">  
  16.                 <extensionElements>  
  17.                     <activiti:taskListener event="complete"  
  18.                         class="org.shirdrn.workflow.activiti.subprocess.CheckBankTask" />  
  19.                 </extensionElements>  
  20.             </userTask>  
  21.             <sequenceFlow id="flow5" sourceRef="task1" targetRef="subProcessJoin" />  
  22.             <userTask id="task2" name="Investigate software" activiti:candidateGroups="engineering" >  
  23.                 <extensionElements>  
  24.                     <activiti:taskListener event="complete"  
  25.                         class="org.shirdrn.workflow.activiti.subprocess.CheckMerchantTask" />  
  26.                 </extensionElements>  
  27.             </userTask>  
  28.             <sequenceFlow id="flow6" sourceRef="task2" targetRef="subProcessJoin" />  
  29.             <parallelGateway id="subProcessJoin" />  
  30.             <sequenceFlow id="flow7" sourceRef="subProcessJoin" targetRef="subProcessEnd" />  
  31.             <endEvent id="subProcessEnd" />  
  32.         </subProcess>  
  33.   
  34.         <sequenceFlow id="flow10" sourceRef="subProcess" targetRef="taskAfterSubProcess" />  
  35.         <userTask id="taskAfterSubProcess" name="Collect message" activiti:candidateGroups="engineering" >  
  36.             <extensionElements>  
  37.                     <activiti:taskListener event="complete"  
  38.                         class="org.shirdrn.workflow.activiti.subprocess.CollectMessageTask" />  
  39.             </extensionElements>  
  40.         </userTask>  
  41.         <sequenceFlow id="flow11" sourceRef="taskAfterSubProcess" targetRef="theEnd" />  
  42.         <endEvent id="theEnd" />  
  43.     </process>  
  44.   
  45. </definitions>  

流程定义中,实现了3个TaskListener,对应的代码分别如下所示:

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.logging.Logger;  
  5.   
  6. import org.activiti.engine.delegate.DelegateTask;  
  7. import org.activiti.engine.impl.pvm.delegate.TaskListener;  
  8.   
  9. public class CheckBankTask implements TaskListener {  
  10.   
  11.     private final Logger log = Logger.getLogger(CheckBankTask.class.getName());  
  12.       
  13.     @SuppressWarnings("unchecked")  
  14.     public void notify(DelegateTask delegateTask) {  
  15.         log.info("i am CheckBankTask.");  
  16.         System.out.println("in : " + delegateTask.getVariables());  
  17.         ((HashMap<String, Object>)delegateTask.getVariables().get("in")).put("next""CheckBankTask");  
  18.         ((HashMap<String, Object>)delegateTask.getVariables().get("out")).put("reponse""subprocess:CheckBankTask->CheckMerchantTask");  
  19.     }  
  20. }  

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. public class CheckMerchantTask implements TaskListener {  
  6.   
  7.     private final Logger log = Logger.getLogger(CheckMerchantTask.class.getName());  
  8.       
  9.     @SuppressWarnings("unchecked")  
  10.     public void notify(DelegateTask delegateTask) {  
  11.         log.info("i am CheckMerchantTask.");  
  12.         System.out.println("in : " + delegateTask.getVariables());  
  13.         ((HashMap<String, Object>)delegateTask.getVariables().get("in")).put("previous""CheckMerchantTask");  
  14.     }  
  15. }  

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.Map;  
  4.   
  5. public class CollectMessageTask implements TaskListener {  
  6.   
  7.     private final Logger log = Logger.getLogger(CollectMessageTask.class.getName());  
  8.       
  9.     @SuppressWarnings("unchecked")  
  10.     public void notify(DelegateTask delegateTask) {  
  11.         log.info("i am CollectMessageTask.");  
  12.         System.out.println("out : " + (Map<String, Object>)delegateTask.getVariables().get("out"));  
  13.         System.out.println("all : " + delegateTask.getVariables());  
  14.     }  
  15. }  

测试用例,代码如下所示:

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import org.activiti.engine.repository.Deployment;  
  8. import org.activiti.engine.runtime.ProcessInstance;  
  9. import org.activiti.engine.task.Task;  
  10. import org.shirdrn.workflow.activiti.AbstractTest;  
  11.   
  12. /** 
  13.  * @author shirdrn 
  14.  */  
  15. public class MySubProcessTest extends AbstractTest {  
  16.   
  17.     @Override  
  18.     protected void initialize() throws Exception {  
  19.         Deployment deployment = repositoryService  
  20.         .createDeployment()  
  21.         .addClasspathResource(  
  22.                 "diagrams/SubProcessTest.MySubprocess.bpmn20.xml")  
  23.         .deploy();    
  24.         deploymentId = deployment.getId();  
  25.     }  
  26.   
  27.     @Override  
  28.     protected void destroy() throws Exception {  
  29.         repositoryService.deleteDeployment(deploymentId, true);   
  30.     }  
  31.       
  32.     public void testSubProcess() {  
  33.         // prepare data packet  
  34.         Map<String, Object> variables = new HashMap<String, Object>();  
  35.         Map<String, Object> subVariables = new HashMap<String, Object>();  
  36.         variables.put("maxTransCount"1000000);  
  37.         variables.put("merchant"new Merchant("ICBC"));  
  38.         variables.put("protocol""UM32");  
  39.         variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  40.         variables.put("in", subVariables);  
  41.         variables.put("out"new HashMap<String, Object>());  
  42.           
  43.         // start process instance  
  44.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("MySubprocess", variables);  
  45.           
  46.         // enter subprocess  
  47.         List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc().list();  
  48.         assertEquals(2, tasks.size());  
  49.           
  50.         for(Task task : tasks) {  
  51.             taskService.complete(task.getId());  
  52.         }  
  53.           
  54.         // leave subprocess  
  55.         Task collectTask = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();  
  56.         assertEquals("Collect message", collectTask.getName());  
  57.           
  58.         Map<String, Object> taskVariables = new HashMap<String, Object>();  
  59.         taskVariables.put("att""anything you need");  
  60.         taskService.setVariable(collectTask.getId(), "oper""shirdrn");  
  61.         taskService.complete(collectTask.getId(), taskVariables);  
  62.     }  
  63.   
  64. }  

运行结果信息,如下所示:

[xhtml]  view plain copy
  1. 2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CheckBankTask notify  
  2. 信息: i am CheckBankTask.  
  3. in : {protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000in={}, out={}}  
  4. 2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CheckMerchantTask notify  
  5. 信息: i am CheckMerchantTask.  
  6. in : {protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000in={next=CheckBankTask}, out={reponse=subprocess:CheckBankTask->CheckMerchantTask}}  
  7. 2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CollectMessageTask notify  
  8. 信息: i am CollectMessageTask.  
  9. out : {reponse=subprocess:CheckBankTask->CheckMerchantTask}  
  10. all : {protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], oper=shirdrnatt=anything you need, maxTransCount=1000000in={previous=CheckMerchantTasknext=CheckBankTask}, out={reponse=subprocess:CheckBankTask->CheckMerchantTask}}  
 

 

调用子流程

实现的子流程,示例如图所示:

对应的流程定义文件Subprocess.Check.bpmn20.xml,如下所示:

[xhtml]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">  
  3.   <process id="CheckSubprocess" name="CheckSubprocess">  
  4.     <startEvent id="startevent4" name="Start"></startEvent>  
  5.     <serviceTask id="servicetask4" name="Check User" activiti:class="org.shirdrn.workflow.activiti.subprocess.BusinessCheck"></serviceTask>  
  6.     <endEvent id="endevent4" name="End"></endEvent>  
  7.     <sequenceFlow id="flow7" name="" sourceRef="startevent4" targetRef="servicetask4"></sequenceFlow>  
  8.     <sequenceFlow id="flow8" name="" sourceRef="servicetask4" targetRef="endevent4"></sequenceFlow>  
  9.   </process>  
  10. </definitions>  

上面的流程定义,和通常定义流程的方式是相同的。流程中,对应的JavaDelegate的实现类,代码如下所示:

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. import org.activiti.engine.delegate.DelegateExecution;  
  6. import org.activiti.engine.delegate.JavaDelegate;  
  7.   
  8. public class BusinessCheck implements JavaDelegate {  
  9.       
  10.     private static final Logger log = Logger.getLogger(BusinessCheck.class.getName());  
  11.       
  12.     @Override  
  13.     public void execute(DelegateExecution execution) throws Exception {  
  14.         // varOutFromMainprocess<->varInSubprocess  
  15.         String varInSubprocess = (String)execution.getVariable("varInSubprocess");  
  16.         log.info("in subprocess get(varInSubprocess): " + varInSubprocess);  
  17.           
  18.         log.info("variavles=" + execution.getVariables());  
  19.         execution.setVariable("s:bc""Subprocess:BusinessCheck");  
  20.         log.info("I am BusinessCheck in subprocess.");    
  21.           
  22.         execution.setVariable("varInSubprocess""BBBB");  
  23.         log.info("in subprocess set(varInSubprocess): " + varInSubprocess);  
  24.     }  
  25. }  

该BusinessCheck类简单用来校验用户数据。

下面看一下主流程,如图所示:

上面的callSubprocess结点对应的就是流程定义中的<callActivity>元素,调用了外部流程。对应的流程定义文件Subprocess.Mainprocess.bpmn20.xml,如下所示:

[xhtml]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"  
  4.     xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"  
  5.     xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"  
  6.     expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">  
  7.     <process id="Mainprocess" name="Main Process">  
  8.         <startEvent id="startevent1" name="Start"></startEvent>  
  9.         <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>  
  10.         <serviceTask id="servicetask1" name="System Initialization" activiti:class="org.shirdrn.workflow.activiti.subprocess.Initialization"></serviceTask>  
  11.         <sequenceFlow id="flow2" name="" sourceRef="servicetask1" targetRef="callSubprocess"></sequenceFlow>  
  12.         <callActivity id="callSubprocess" calledElement="CheckSubprocess" >   
  13.           <extensionElements>   
  14.                   <activiti:in source="varOutFromMainprocess" target="varInSubprocess" />   
  15.                   <activiti:out source="varInSubprocess" target="varOutFromSubprocess" />   
  16.           </extensionElements>   
  17.         </callActivity>  
  18.         <sequenceFlow id="flow3" name="" sourceRef="callSubprocess" targetRef="servicetask2"></sequenceFlow>  
  19.         <serviceTask id="servicetask2" name="Do Transaction" activiti:class="org.shirdrn.workflow.activiti.subprocess.DoTransaction"></serviceTask>  
  20.         <sequenceFlow id="flow4" name="" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow>  
  21.         <endEvent id="endevent1" name="End"></endEvent>  
  22.     </process>  
  23. </definitions>  

需要说明的是,对于主流程与子流程之间进行数据交换,需要在<callActivity>元素中进行配置,通过执行“传入”、“传出”变量的方式来进行。片段如下所示:

[xhtml]  view plain copy
  1. <callActivity id="callSubprocess" calledElement="CheckSubprocess" >   
  2.   <extensionElements>   
  3.           <activiti:in source="varOutFromMainprocess" target="varInSubprocess" />   
  4.           <activiti:out source="varInSubprocess" target="varOutFromSubprocess" />   
  5.   </extensionElements>   
  6. </callActivity>  

我们可以通过在主流程中设置一个变量为varOutFromMainprocess,并指定对应的输入数据,根据流程定义,会将变量varOutFromMainprocess对应的值,传递给子流程中的变量varInSubprocess,只需要在子流程中获取变量varInSubprocess的值即可。从子流程中传出数据的道理是类似的。上面实现了2个JavaDelegate处理类,代码分别如下所示:

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class Initialization implements JavaDelegate {  
  6.       
  7.     private static final Logger log = Logger.getLogger(Initialization.class.getName());  
  8.       
  9.     @Override  
  10.     public void execute(DelegateExecution execution) throws Exception {  
  11.         log.info("variavles=" + execution.getVariables());  
  12.         execution.setVariable("m:i""Mainprocess:Initialization");  
  13.         log.info("I am Initialization in mainprocess.");  
  14.           
  15.         execution.setVariable("varOutFromMainprocess""AAAA");  
  16.         log.info("in mainprocess set(varOutFromMainprocess): " + execution.getVariable("varOutFromMainprocess"));  
  17.     }  
  18. }  

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class DoTransaction implements JavaDelegate {  
  6.       
  7.     private static final Logger log = Logger.getLogger(DoTransaction.class.getName());  
  8.       
  9.     @Override  
  10.     public void execute(DelegateExecution execution) throws Exception {  
  11.         // varInSubprocess<->varOutFromSubprocess  
  12.         String varOutFromSubprocess = (String)execution.getVariable("varOutFromSubprocess");  
  13.         log.info("in mainprocess get(varOutFromSubprocess): " + varOutFromSubprocess);  
  14.           
  15.         log.info("variavles=" + execution.getVariables());  
  16.         execution.setVariable("m:dt""Mainprocess:DoTransaction");  
  17.         log.info("I am DoTransaction in mainprocess.");  
  18.     }  
  19. }  

实现的测试用例,代码如下所示:

 

[java]  view plain copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.activiti.engine.repository.Deployment;  
  7. import org.activiti.engine.runtime.ProcessInstance;  
  8. import org.shirdrn.workflow.activiti.AbstractTest;  
  9.   
  10. /** 
  11.  * @author shirdrn 
  12.  */  
  13. public class MainprocessTest extends AbstractTest {  
  14.   
  15.     @Override  
  16.     protected void initialize() throws Exception {  
  17.         Deployment deployment = repositoryService  
  18.         .createDeployment()  
  19.         .addClasspathResource(  
  20.                 "diagrams/Subprocess.Check.bpmn20.xml")  
  21.         .deploy();    
  22.         deploymentIdList.add(deployment.getId());  
  23.           
  24.         deployment = repositoryService  
  25.         .createDeployment()  
  26.         .addClasspathResource(  
  27.                 "diagrams/Subprocess.Mainprocess.bpmn20.xml")  
  28.         .deploy();    
  29.         deploymentIdList.add(deployment.getId());  
  30.     }  
  31.   
  32.     @Override  
  33.     protected void destroy() throws Exception {  
  34.         for(String deployment : deploymentIdList) {  
  35.             repositoryService.deleteDeployment(deployment, true);     
  36.         }  
  37.     }  
  38.       
  39.     public void testSubProcess() {  
  40.         // prepare data packet  
  41.         Map<String, Object> variables = new HashMap<String, Object>();  
  42.         Map<String, Object> subVariables = new HashMap<String, Object>();  
  43.         variables.put("protocol""UM32");  
  44.         variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  45.         variables.put("in", subVariables);  
  46.         variables.put("out"new HashMap<String, Object>());  
  47.           
  48.         // start process instance  
  49.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("Mainprocess", variables);  
  50.           
  51.         assertEquals(true, pi.isEnded());  
  52.     }  
  53.   
  54. }  

 代码中org.shirdrn.workflow.activiti.AbstractTest类可以参考:Activiti 5.3:流程活动自动与手工触发执行里面。上述测试程序运行结果如下所示:

[xhtml]  view plain copy
  1. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute  
  2. 信息: variavles={protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, in={}, out={}}  
  3. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute  
  4. 信息: I am Initialization in mainprocess.  
  5. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute  
  6. 信息: in mainprocess set(varOutFromMainprocess): AAAA  
  7. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute  
  8. 信息: in subprocess get(varInSubprocess): AAAA  
  9. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute  
  10. 信息: variavles={varInSubprocess=AAAA}  
  11. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute  
  12. 信息: I am BusinessCheck in subprocess.  
  13. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute  
  14. 信息: in subprocess set(varInSubprocess): AAAA  
  15. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute  
  16. 信息: in mainprocess get(varOutFromSubprocess): BBBB  
  17. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute  
  18. 信息: variavles={protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, varOutFromSubprocess=BBBBvarOutFromMainprocess=AAAAin={}, out={}, m:i=Mainprocess:Initialization}  
  19. 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute  
  20. 信息: I am DoTransaction in mainprocess.  

 

你可能感兴趣的:(java,object,XHTML,Deployment,initialization,subprocess)