Activiti 5.3:流程活动自动与手工触发执行(转)

版权声明:本文为博主原创文章,未经博主允许不得转载。



Activiti 5.3支持流程活动自动执行与手工触发执行。其中,自动执行是指,在启动流程之前,准备流程所需要的控制流程进度的变量数据,启动流程之后,无需外部干预,就能够按照预定义的流程执行;手工触发执行是指,执行到流程中某个个结点后流程暂时停止运行,直到收到外部发送的信号以后,才会继续向前推进,这样情况可以更加精细地控制流程。

下面主要通过基于Activiti 5.3的<parallelGateway>、<serviceTask>、<receiveTask>、<userTask>元素来看一下。首先,我们在测试的过程中,用到JUnit 3.x,为了方便,这里给了一层封装,代码如下所示:

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import org.activiti.engine.FormService;  
  6. import org.activiti.engine.HistoryService;  
  7. import org.activiti.engine.IdentityService;  
  8. import org.activiti.engine.ManagementService;  
  9. import org.activiti.engine.ProcessEngine;  
  10. import org.activiti.engine.ProcessEngines;  
  11. import org.activiti.engine.RepositoryService;  
  12. import org.activiti.engine.RuntimeService;  
  13. import org.activiti.engine.TaskService;  
  14.   
  15. /** 
  16.  * @author shirdrn 
  17.  */  
  18. public abstract class AbstractTest extends TestCase {  
  19.   
  20.     private ProcessEngine processEngine;  
  21.     protected String deploymentId;  
  22.     protected RepositoryService repositoryService;  
  23.     protected RuntimeService runtimeService;  
  24.     protected TaskService taskService;  
  25.     protected FormService formService;  
  26.     protected HistoryService historyService;  
  27.     protected IdentityService identityService;  
  28.     protected ManagementService managementService;  
  29.       
  30.     @Override  
  31.     protected void setUp() throws Exception {  
  32.         super.setUp();  
  33.         if(processEngine==null) {  
  34.             processEngine = ProcessEngines.getDefaultProcessEngine();  
  35.         }  
  36.         repositoryService = processEngine.getRepositoryService();  
  37.         runtimeService = processEngine.getRuntimeService();  
  38.         taskService = processEngine.getTaskService();  
  39.         formService = processEngine.getFormService();  
  40.         historyService = processEngine.getHistoryService();  
  41.         identityService = processEngine.getIdentityService();  
  42.         managementService = processEngine.getManagementService();  
  43.         initialize();  
  44.     }  
  45.       
  46.     @Override  
  47.     protected void tearDown() throws Exception {  
  48.         super.tearDown();  
  49.         destroy();  
  50.     }  
  51.       
  52.     protected abstract void initialize() throws Exception;  
  53.       
  54.     protected abstract void destroy() throws Exception;  
  55. }  

这里面,主要是在测试之前做一些初始化工作,主要包括流程引擎实例的构建,及其流程提供的基本服务。下面测试会用到该抽象类。

自动执行

<serviceTask>元素,可以实现自动活动,语法如下所示:

[xhtml]  view plain  copy
  1. <serviceTask id="serviceTaskId" name="serviceTaskName"  
  2. iviti:class="org.shirdrn.workflow.activiti.gateway.ServiceTaskClass"/>  

其中,activiti:class属性为该结点对应的处理类,该类要求实现org.activiti.engine.delegate.JavaDelegate接口,该接口定义如下所示:

[java]  view plain  copy
  1. package org.activiti.engine.delegate;  
  2.   
  3. public interface JavaDelegate {  
  4.     
  5.   void execute(DelegateExecution execution) throws Exception;  
  6.   
  7. }  

execute方法的参数DelegateExecution execution可以在流程中各个结点之间传递流程变量。

下面给出一个具体的例子:

自动执行的流程,如图所示:

 

对应的流程定义文件为GatewayTest.testAutomaticForkJoin.bpmn20.xml,如下所示:

[c-sharp]  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="AutomaticParalellBasedForkJoin" name="AutomaticParalellBasedForkJoin">  
  4.     <startEvent id="startevent7" name="Start"></startEvent>  
  5.     <parallelGateway id="parallelgateway12" name="Fork"></parallelGateway>  
  6.     <serviceTask id="servicetask3" name="Task 1" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTask1"></serviceTask>  
  7.     <serviceTask id="servicetask4" name="Task 2" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTask2"></serviceTask>  
  8.     <serviceTask id="servicetask5" name="Task 3" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTask3"></serviceTask>  
  9.     <parallelGateway id="parallelgateway13" name="First Join"></parallelGateway>  
  10.     <serviceTask id="servicetask6" name="Task 4" activiti:class="org.shirdrn.workflow.activiti.gateway.ServiceTask4"></serviceTask>  
  11.     <parallelGateway id="parallelgateway14"></parallelGateway>  
  12.     <endEvent id="endevent7" name="End"></endEvent>  
  13.     <sequenceFlow id="flow45" name="" sourceRef="startevent7" targetRef="parallelgateway12"></sequenceFlow>  
  14.     <sequenceFlow id="flow46" name="" sourceRef="parallelgateway12" targetRef="servicetask3"></sequenceFlow>  
  15.     <sequenceFlow id="flow47" name="" sourceRef="parallelgateway12" targetRef="servicetask4"></sequenceFlow>  
  16.     <sequenceFlow id="flow48" name="" sourceRef="parallelgateway12" targetRef="servicetask5"></sequenceFlow>  
  17.     <sequenceFlow id="flow49" name="" sourceRef="servicetask3" targetRef="parallelgateway13"></sequenceFlow>  
  18.     <sequenceFlow id="flow50" name="" sourceRef="servicetask4" targetRef="parallelgateway13"></sequenceFlow>  
  19.     <sequenceFlow id="flow51" name="" sourceRef="servicetask5" targetRef="parallelgateway14"></sequenceFlow>  
  20.     <sequenceFlow id="flow52" name="" sourceRef="parallelgateway13" targetRef="servicetask6"></sequenceFlow>  
  21.     <sequenceFlow id="flow53" name="" sourceRef="servicetask6" targetRef="parallelgateway14"></sequenceFlow>  
  22.     <sequenceFlow id="flow54" name="" sourceRef="parallelgateway14" targetRef="endevent7"></sequenceFlow>  
  23.   </process>  
  24. </definitions>  

上述流程定义中,一共定义了4个ServiceTask,模拟实现代码如下所示:

 

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  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 ServiceTask1 implements JavaDelegate {  
  9.   
  10.     private final Logger log = Logger.getLogger(ServiceTask1.class.getName());  
  11.   
  12.     @Override  
  13.     public void execute(DelegateExecution execution) throws Exception {  
  14.         Thread.sleep(10000);  
  15.         log.info("variavles=" + execution.getVariables());  
  16.         execution.setVariable("task1""I am task 1");  
  17.         log.info("I am task 1.");         
  18.     }  
  19. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class ServiceTask2 implements JavaDelegate {  
  6.   
  7.     private final Logger log = Logger.getLogger(ServiceTask2.class.getName());  
  8.   
  9.     @Override  
  10.     public void execute(DelegateExecution execution) throws Exception {  
  11.         Thread.sleep(10000);  
  12.         log.info("variavles=" + execution.getVariables());  
  13.         execution.setVariable("task2""I am task 2");  
  14.         log.info("I am task 2.");  
  15.     }  
  16. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class ServiceTask3 implements JavaDelegate {  
  6.   
  7.     private final Logger log = Logger.getLogger(ServiceTask3.class.getName());  
  8.   
  9.     @Override  
  10.     public void execute(DelegateExecution execution) throws Exception {  
  11.         Thread.sleep(10000);  
  12.         log.info("variavles=" + execution.getVariables());  
  13.         execution.setVariable("task3""I am task 3");  
  14.         log.info("I am task 3.");         
  15.     }  
  16. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class ServiceTask4 implements JavaDelegate {  
  6.   
  7.     private final Logger log = Logger.getLogger(ServiceTask4.class.getName());  
  8.   
  9.     @Override  
  10.     public void execute(DelegateExecution execution) throws Exception {  
  11.         Thread.sleep(10000);  
  12.         log.info("variavles=" + execution.getVariables());  
  13.         execution.setVariable("task4""I am task 4");  
  14.         log.info("I am task 4.");     
  15.     }  
  16. }  

测试代码,如下所示:

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import org.activiti.engine.runtime.ProcessInstance;  
  4. import org.activiti.engine.test.Deployment;  
  5. import org.shirdrn.workflow.activiti.AbstractTest;  
  6.   
  7. /** 
  8.  * @author shirdrn 
  9.  */  
  10. public class AutomaticParallelGatewayTest extends AbstractTest {  
  11.   
  12.     private String deploymentId;  
  13.       
  14.     @Override  
  15.     protected void initialize() throws Exception {  
  16.         deploymentId = repositoryService.createDeployment()  
  17.             .addClasspathResource("diagrams/GatewayTest.testAutomaticForkJoin.bpmn20.xml")  
  18.             .deploy().getId();  
  19.     }  
  20.   
  21.     @Override  
  22.     protected void destroy() throws Exception {  
  23.         repositoryService.deleteDeployment(deploymentId, true);  
  24.     }  
  25.       
  26.     @Deployment  
  27.     public void testForkJoin() {  
  28.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("AutomaticParalellBasedForkJoin");  
  29.         assertEquals(true, pi.isEnded());  
  30.     }  
  31. }  

只需要启动一个流程实例,它会自动执行到结束。这种情况下,你不需要关注流程的执行进度,而只需要把精力集中在每个结点的处理逻辑(通常是简单或者复杂的商业逻辑)上,运行结果如下所示:

[xhtml]  view plain  copy
  1. 2011-3-23 11:50:12 org.shirdrn.workflow.activiti.gateway.ServiceTask1 execute  
  2. 信息: variavles={}  
  3. 2011-3-23 11:50:12 org.shirdrn.workflow.activiti.gateway.ServiceTask1 execute  
  4. 信息: I am task 1.  
  5. 2011-3-23 11:50:22 org.shirdrn.workflow.activiti.gateway.ServiceTask2 execute  
  6. 信息: variavles={task1=I am task 1}  
  7. 2011-3-23 11:50:22 org.shirdrn.workflow.activiti.gateway.ServiceTask2 execute  
  8. 信息: I am task 2.  
  9. 2011-3-23 11:50:32 org.shirdrn.workflow.activiti.gateway.ServiceTask4 execute  
  10. 信息: variavles={task1=I am task 1, task2=I am task 2}  
  11. 2011-3-23 11:50:32 org.shirdrn.workflow.activiti.gateway.ServiceTask4 execute  
  12. 信息: I am task 4.  
  13. 2011-3-23 11:50:42 org.shirdrn.workflow.activiti.gateway.ServiceTask3 execute  
  14. 信息: variavles={task1=I am task 1, task2=I am task 2, task4=I am task 4}  
  15. 2011-3-23 11:50:42 org.shirdrn.workflow.activiti.gateway.ServiceTask3 execute  
  16. 信息: I am task 3.  
  

手工触发执行

通过<receiveTask>和<userTask>元素都可以实现流程的手工触发执行。

基于<receiveTask>

实现的流程,如图所示:

对应的流程定义文件Task.ReceiveTask.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="MyReceiveTask" name="MyReceiveTask">  
  4.     <startEvent id="startevent4" name="Start"></startEvent>  
  5.     <receiveTask id="receivetask1" name="Check bank">  
  6.       <extensionElements>  
  7.         <activiti:executionListener event="start" class="org.shirdrn.workflow.activiti.task.CheckBankReceiveTask"></activiti:executionListener>  
  8.       </extensionElements>  
  9.     </receiveTask>  
  10.     <receiveTask id="receivetask2" name="Check merchant">  
  11.       <extensionElements>  
  12.         <activiti:executionListener event="start" class="org.shirdrn.workflow.activiti.task.CheckMerchantReceiveTask"></activiti:executionListener>  
  13.       </extensionElements>  
  14.     </receiveTask>  
  15.     <endEvent id="endevent5" name="End"></endEvent>  
  16.     <sequenceFlow id="flow16" name="" sourceRef="startevent4" targetRef="receivetask1"></sequenceFlow>  
  17.     <sequenceFlow id="flow17" name="" sourceRef="receivetask1" targetRef="receivetask2"></sequenceFlow>  
  18.     <sequenceFlow id="flow18" name="" sourceRef="receivetask2" targetRef="endevent5"></sequenceFlow>  
  19.   </process>  
  20. </definitions>  

上述流程定义中,对应的两个处理类,代码分别如下所示:

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

上面还用到一个org.shirdrn.workflow.activiti.subprocess.Merchant类,该类必须支持序列化,如下所示: 

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.subprocess;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Merchant implements Serializable {  
  6.     private static final long serialVersionUID = 1L;  
  7.     public Merchant(String merchantId, int priority, short serviceType, short status) {  
  8.         super();  
  9.         this.merchantId = merchantId;  
  10.         this.priority = priority;  
  11.         this.serviceType = serviceType;  
  12.         this.status = status;  
  13.     }  
  14.     public Merchant(String merchantId) {  
  15.         this(merchantId, -1, (short)0, (short)0);  
  16.     }  
  17.     private String merchantId;  
  18.     private int priority = -1;  
  19.     private short serviceType = 0;  
  20.     private short status = 0;  
  21.     public String getMerchantId() {  
  22.         return merchantId;  
  23.     }  
  24.     public void setMerchantId(String merchantId) {  
  25.         this.merchantId = merchantId;  
  26.     }  
  27.     public int getPriority() {  
  28.         return priority;  
  29.     }  
  30.     public void setPriority(int priority) {  
  31.         this.priority = priority;  
  32.     }  
  33.     public short getServiceType() {  
  34.         return serviceType;  
  35.     }  
  36.     public void setServiceType(short serviceType) {  
  37.         this.serviceType = serviceType;  
  38.     }  
  39.     public short getStatus() {  
  40.         return status;  
  41.     }  
  42.     public void setStatus(short status) {  
  43.         this.status = status;  
  44.     }  
  45.     @Override  
  46.     public String toString() {  
  47.         return "Merchant[" + merchantId + "]";  
  48.     }  
  49. }  

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

 

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.task;  
  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.Execution;  
  9. import org.activiti.engine.runtime.ProcessInstance;  
  10. import org.shirdrn.workflow.activiti.AbstractTest;  
  11. import org.shirdrn.workflow.activiti.subprocess.Merchant;  
  12.   
  13. /** 
  14.  * @author shirdrn 
  15.  */  
  16. public class MyReceiveTaskTest extends AbstractTest {  
  17.   
  18.     @Override  
  19.     protected void initialize() throws Exception {  
  20.         Deployment deployment = repositoryService  
  21.         .createDeployment()  
  22.         .addClasspathResource(  
  23.                 "diagrams/Task.ReceiveTask.bpmn20.xml")  
  24.         .deploy();    
  25.         deploymentId = deployment.getId();  
  26.     }  
  27.   
  28.     @Override  
  29.     protected void destroy() throws Exception {  
  30.         repositoryService.deleteDeployment(deploymentId, true);   
  31.     }  
  32.       
  33.     public void testSubProcess() {  
  34.         // prepare data packet  
  35.         Map<String, Object> variables = new HashMap<String, Object>();  
  36.         Map<String, Object> subVariables = new HashMap<String, Object>();  
  37.         variables.put("maxTransCount"1000000);  
  38.         variables.put("merchant"new Merchant("ICBC"));  
  39.         variables.put("protocol""UM32");  
  40.         variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  41.         variables.put("in", subVariables);  
  42.         variables.put("out"new HashMap<String, Object>());  
  43.           
  44.         // start process instance  
  45.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("MyReceiveTask", variables);  
  46.         List<Execution> executions = runtimeService.createExecutionQuery().list();  
  47.         assertEquals(1, executions.size());  
  48.           
  49.         Execution execution = runtimeService.createExecutionQuery().singleResult();  
  50.         runtimeService.setVariable(execution.getId(), "type""receiveTask");  
  51.         runtimeService.signal(execution.getId());  
  52.         assertEquals(1, executions.size());  
  53.           
  54.         execution = runtimeService.createExecutionQuery().list().get(0);  
  55.         assertNotNull(execution);  
  56.         runtimeService.setVariable(execution.getId(), "oper""shirdrn");  
  57.         runtimeService.signal(execution.getId());  
  58.     }  
  59.   
  60. }  

运行结果如下所示:

[xhtml]  view plain  copy
  1. 2011-3-23 12:51:35 org.shirdrn.workflow.activiti.task.CheckBankReceiveTask execute  
  2. 信息: i am CheckBankReceiveTask.  
  3. in : {protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000in={}, out={}}  
  4. 2011-3-23 12:51:35 org.shirdrn.workflow.activiti.task.CheckMerchantReceiveTask execute  
  5. 信息: i am CheckMerchantReceiveTask.  
  6. in : {protocol=UM32repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000type=receiveTaskin={}, out={}}  

基于<userTask>

实现的流程,如图所示:

对应的流程定义文件,如下所示:

[xhtml]  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="Umpay">  
  5.     <process id="ParalellBasedForkJoin">  
  6.         <startEvent id="theStart" />  
  7.         <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />  
  8.         <parallelGateway id="fork" name="Fork" />  
  9.         <sequenceFlow sourceRef="fork" targetRef="task1" />  
  10.         <sequenceFlow sourceRef="fork" targetRef="task2" />  
  11.         <sequenceFlow sourceRef="fork" targetRef="task3" />  
  12.         <userTask id="task1" name="Task 1">  
  13.             <extensionElements>  
  14.                 <activiti:taskListener event="complete"  
  15.                     class="org.shirdrn.workflow.activiti.gateway.Task1Listener" />  
  16.             </extensionElements>  
  17.         </userTask>  
  18.         <sequenceFlow sourceRef="task1" targetRef="firstJoin" />  
  19.         <userTask id="task2" name="Task 2">  
  20.             <extensionElements>  
  21.                 <activiti:taskListener event="complete"  
  22.                     class="org.shirdrn.workflow.activiti.gateway.Task2Listener" />  
  23.             </extensionElements>  
  24.         </userTask>  
  25.         <sequenceFlow sourceRef="task2" targetRef="firstJoin" />  
  26.         <userTask id="task3" name="Task 3">  
  27.             <extensionElements>  
  28.                 <activiti:taskListener event="complete"  
  29.                     class="org.shirdrn.workflow.activiti.gateway.Task3Listener" />  
  30.             </extensionElements>  
  31.         </userTask>  
  32.         <sequenceFlow sourceRef="task3" targetRef="secondJoin" />  
  33.         <parallelGateway id="firstJoin" name="First Join" />  
  34.         <sequenceFlow sourceRef="firstJoin" targetRef="task4" />  
  35.         <userTask id="task4" name="Task 4">  
  36.             <extensionElements>  
  37.                 <activiti:taskListener event="complete"  
  38.                     class="org.shirdrn.workflow.activiti.gateway.Task4Listener" />  
  39.             </extensionElements>  
  40.         </userTask>  
  41.         <sequenceFlow sourceRef="task4" targetRef="secondJoin" />  
  42.         <parallelGateway id="secondJoin" />  
  43.         <sequenceFlow sourceRef="secondJoin" targetRef="theEnd" />  
  44.         <endEvent id="theEnd" />  
  45.     </process>  
  46. </definitions>  
  

我们看一下上述定义中,如下配置片段:

[xhtml]  view plain  copy
  1. <userTask id="task1" name="Task 1">  
  2.     <extensionElements>  
  3.         <activiti:taskListener event="complete"  
  4.             class="org.shirdrn.workflow.activiti.gateway.Task1Listener" />  
  5.     </extensionElements>  
  6. </userTask>  

<activiti:taskListener>元素的event属性,它一共包含三种事件:"create"、"assignment"、"complete",分别表示结点执行处理逻辑的时机为:在处理类实例化时、在结点处理逻辑被指派时、在结点处理逻辑执行完成时,可以根据自己的需要进行指定。

上述流程定义中,4个任务结点对应的处理类,代码分别如下所示:

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. import org.activiti.engine.delegate.DelegateTask;  
  6. import org.activiti.engine.impl.pvm.delegate.TaskListener;  
  7.   
  8. public class Task1Listener implements TaskListener {  
  9.   
  10.     private final Logger log = Logger.getLogger(Task1Listener.class.getName());  
  11.       
  12.     @Override  
  13.     public void notify(DelegateTask delegateTask) {  
  14.         try {  
  15.             Thread.sleep(10000);  
  16.         } catch (InterruptedException e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.         log.info("I am task 1.");  
  20.     }  
  21. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class Task2Listener implements TaskListener {  
  6.   
  7.     private final Logger log = Logger.getLogger(Task2Listener.class.getName());  
  8.       
  9.     @Override  
  10.     public void notify(DelegateTask delegateTask) {  
  11.         try {  
  12.             Thread.sleep(10000);  
  13.         } catch (InterruptedException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.         log.info("I am task 2.");  
  17.     }  
  18. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class Task3Listener implements TaskListener {  
  6.   
  7.     private final Logger log = Logger.getLogger(Task3Listener.class.getName());  
  8.       
  9.     @Override  
  10.     public void notify(DelegateTask delegateTask) {  
  11.         try {  
  12.             Thread.sleep(5000);  
  13.         } catch (InterruptedException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.         log.info("I am task 3.");  
  17.     }  
  18. }  
[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.logging.Logger;  
  4.   
  5. public class Task4Listener implements TaskListener {  
  6.   
  7.     private final Logger log = Logger.getLogger(Task4Listener.class.getName());  
  8.       
  9.     @Override  
  10.     public void notify(DelegateTask delegateTask) {  
  11.         try {  
  12.             Thread.sleep(5000);  
  13.         } catch (InterruptedException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.         log.info("I am task 4.");  
  17.     }  
  18. }  

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

[java]  view plain  copy
  1. package org.shirdrn.workflow.activiti.gateway;  
  2.   
  3. import java.util.Date;  
  4. import java.util.List;  
  5.   
  6. import org.activiti.engine.runtime.ProcessInstance;  
  7. import org.activiti.engine.task.Task;  
  8. import org.activiti.engine.task.TaskQuery;  
  9. import org.activiti.engine.test.Deployment;  
  10. import org.shirdrn.workflow.activiti.AbstractTest;  
  11.   
  12. /** 
  13.  * @author shirdrn 
  14.  */  
  15. public class ParallelGatewayTest extends AbstractTest {  
  16.   
  17.     private String deploymentId;  
  18.     private Date start = null;  
  19.     private Date end = null;  
  20.       
  21.     @Override  
  22.     protected void initialize() throws Exception {  
  23.         deploymentId = repositoryService.createDeployment()  
  24.             .addClasspathResource("diagrams/GatewayTest.testForkJoin.bpmn20.xml")  
  25.             .deploy().getId();  
  26.     }  
  27.   
  28.     @Override  
  29.     protected void destroy() throws Exception {  
  30.         repositoryService.deleteDeployment(deploymentId, true);  
  31.     }  
  32.       
  33.     @Deployment  
  34.     public void testUnbalancedForkJoin() {  
  35.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("ParalellBasedForkJoin");  
  36.         TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();  
  37.   
  38.         List<Task> tasks = query.list();        
  39.         assertEquals(3, tasks.size());  
  40.         start = new Date();  
  41.         for(Task task : tasks) {  
  42.             taskService.complete(task.getId());  
  43.             end = new Date();  
  44.             System.out.println("" + (end.getTime()-start.getTime()) + "ms.");  
  45.         }  
  46.   
  47.         tasks = query.list();  
  48.         assertEquals(1, tasks.size());  
  49.         for(Task task : tasks) {  
  50.             taskService.complete(task.getId());  
  51.             end = new Date();  
  52.             System.out.println("" + (end.getTime()-start.getTime()) + "ms.");  
  53.         }  
  54.         end = new Date();  
  55.         System.out.println("" + (end.getTime()-start.getTime()) + "ms.");  
  56.     }  
  57. }  

运行结果如下所示:

[xhtml]  view plain  copy
  1. 2011-3-23 12:50:09 org.shirdrn.workflow.activiti.gateway.Task1Listener notify  
  2. 信息: I am task 1.  
  3. 10031ms.  
  4. 2011-3-23 12:50:19 org.shirdrn.workflow.activiti.gateway.Task2Listener notify  
  5. 信息: I am task 2.  
  6. 20078ms.  
  7. 2011-3-23 12:50:24 org.shirdrn.workflow.activiti.gateway.Task3Listener notify  
  8. 信息: I am task 3.  
  9. 25093ms.  
  10. 2011-3-23 12:50:29 org.shirdrn.workflow.activiti.gateway.Task4Listener notify  
  11. 信息: I am task 4.  
  12. 30172ms.  
  13. 30172ms.  
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页