工作流Activiti的学习总结(九)Activiti手工执行的应用(ReceiveTask实现方式)

来源:互联网 发布:python sort函数 编辑:程序博客网 时间:2024/05/16 00:51

 工作流模拟的业务情景如下:
           1.用户到银行转账业务
           2.银行工作人员查询用户余额
           3.银行工作人员帮助用户转账

 手工触发执行是指,执行到流程中某个个结点后流程暂时停止运行,直到收到外部发送的信号
  以后,才会继续向前推进,这样情况可以更加精细地控制流程。 

针对用户手动执行的任务可以采用手工触发执行 
       通过<receiveTask>和<userTask>元素都可以实现流程的手工触发执行。

 

本文讲解ReceiveTask方式实现:

配置如下:

 

Xml代码  收藏代码
  1. <receiveTask id="receivetask2" name="开始转账">  
  2.    <extensionElements>  
  3.       <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckMerchantMoneyTask"></activiti:executionListener>  
  4.    </extensionElements>  
  5.  </receiveTask>  

 

 

流程图如下:

 

流程配置如下:

 

Xml代码  收藏代码
  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="BankUserTask" name="BankUserTask">  
  4.     <documentation>Place documentation for the 'BankUserTask' process here.</documentation>  
  5.     <startEvent id="startevent1" name="准备转账业务"></startEvent>  
  6.     <endEvent id="endevent1" name="转账结束"></endEvent>  
  7.     <receiveTask id="receivetask1" name="检查账户余额">  
  8.      <extensionElements>  
  9.         <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckBankAccountMoneyTask"/>  
  10.      </extensionElements>  
  11.     </receiveTask>  
  12.     <receiveTask id="receivetask2" name="开始转账">  
  13.       <extensionElements>  
  14.          <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckMerchantMoneyTask"></activiti:executionListener>  
  15.       </extensionElements>  
  16.     </receiveTask>  
  17.     <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="receivetask1"></sequenceFlow>  
  18.     <sequenceFlow id="flow2" name="" sourceRef="receivetask1" targetRef="receivetask2"></sequenceFlow>  
  19.     <sequenceFlow id="flow3" name="" sourceRef="receivetask2" targetRef="endevent1"></sequenceFlow>  
  20.     <sequenceFlow id="flow4" name="" sourceRef="receivetask1" targetRef="endevent1"></sequenceFlow>  
  21.   </process>  
  22.   <bpmndi:BPMNDiagram id="BPMNDiagram_BankUserTask">  
  23.     <bpmndi:BPMNPlane bpmnElement="BankUserTask" id="BPMNPlane_BankUserTask">  
  24.       <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">  
  25.         <omgdc:Bounds height="35" width="35" x="76" y="218"></omgdc:Bounds>  
  26.       </bpmndi:BPMNShape>  
  27.       <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">  
  28.         <omgdc:Bounds height="35" width="35" x="590" y="220"></omgdc:Bounds>  
  29.       </bpmndi:BPMNShape>  
  30.       <bpmndi:BPMNShape bpmnElement="receivetask1" id="BPMNShape_receivetask1">  
  31.         <omgdc:Bounds height="55" width="105" x="160" y="210"></omgdc:Bounds>  
  32.       </bpmndi:BPMNShape>  
  33.       <bpmndi:BPMNShape bpmnElement="receivetask2" id="BPMNShape_receivetask2">  
  34.         <omgdc:Bounds height="55" width="105" x="340" y="210"></omgdc:Bounds>  
  35.       </bpmndi:BPMNShape>  
  36.       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">  
  37.         <omgdi:waypoint x="111" y="235"></omgdi:waypoint>  
  38.         <omgdi:waypoint x="160" y="237"></omgdi:waypoint>  
  39.       </bpmndi:BPMNEdge>  
  40.       <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">  
  41.         <omgdi:waypoint x="265" y="237"></omgdi:waypoint>  
  42.         <omgdi:waypoint x="340" y="237"></omgdi:waypoint>  
  43.       </bpmndi:BPMNEdge>  
  44.       <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">  
  45.         <omgdi:waypoint x="445" y="237"></omgdi:waypoint>  
  46.         <omgdi:waypoint x="590" y="237"></omgdi:waypoint>  
  47.       </bpmndi:BPMNEdge>  
  48.       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">  
  49.         <omgdi:waypoint x="265" y="237"></omgdi:waypoint>  
  50.         <omgdi:waypoint x="212" y="338"></omgdi:waypoint>  
  51.         <omgdi:waypoint x="385" y="338"></omgdi:waypoint>  
  52.         <omgdi:waypoint x="607" y="338"></omgdi:waypoint>  
  53.         <omgdi:waypoint x="607" y="255"></omgdi:waypoint>  
  54.       </bpmndi:BPMNEdge>  
  55.     </bpmndi:BPMNPlane>  
  56.   </bpmndi:BPMNDiagram>  
  57. </definitions>  

 

 

代码实现如下:

 

 

Java代码  收藏代码
  1. /** 
  2. package com.easyway.workflow.activiti; 
  3. import java.util.HashMap; 
  4. /** 
  5.  * 银行工作人员开始查询用户余额的事件 
  6.  *  
  7.  * @author longgangbai 
  8.  *  
  9.  * 2011-12-17  上午09:37:50 
  10.  */  
  11. public class CheckBankAccountMoneyTask implements JavaDelegate {  
  12.   
  13.     private final Logger log = Logger.getLogger(CheckBankAccountMoneyTask.class.getName());  
  14.   
  15.     @SuppressWarnings("unchecked")  
  16.     @Override  
  17.     public void execute(DelegateExecution execution) throws Exception {  
  18.         log.info("根据输入参数,开始检查银行账户余额........");  
  19.         System.out.println("in : " + execution.getVariables());  
  20.         ((HashMap<String, Object>)execution.getVariables().get("in")).put("next""CheckBankTask");  
  21.         ((HashMap<String, Object>)execution.getVariables().get("out")).put("reponse""subprocess:CheckBankReceiveTask->CheckMerchantReceiveTask");          
  22.     }  
  23. }  

 

 

Java代码  收藏代码
  1. package com.easyway.workflow.activiti;  
  2.   
  3. import java.util.HashMap;  
  4. /** 
  5.  *  
  6.  * 银行工作人员开始转账过程 
  7.  * @author longgangbai 
  8.  *  
  9.  * 2011-12-17  下午09:39:14 
  10.  */  
  11. public class CheckMerchantMoneyTask implements JavaDelegate {  
  12.   
  13.     private final Logger log = Logger.getLogger(CheckMerchantMoneyTask.class.getName());  
  14.       
  15.     @SuppressWarnings("unchecked")  
  16.     @Override  
  17.     public void execute(DelegateExecution execution) throws Exception {  
  18.         log.info("正在转账中.........");  
  19.         System.out.println("in : " + execution.getVariables());  
  20.         ((HashMap<String, Object>)execution.getVariables().get("in")).put("previous""CheckMerchantReceiveTask");  
  21.     }  
  22. }  

 

 

Java代码  收藏代码
  1. package com.easyway.workflow.activiti;  
  2.   
  3.   
  4. import junit.framework.TestCase;  
  5. /** 
  6.  * 主要是在测试之前做一些初始化工作,主要包括流程引擎实例 
  7.  * 的构建,及其流程提供的基本服务。 
  8.  * 目的:让开发者熟悉工作流使用过程使用的几个步骤 
  9.  * 1.加载相关的工作流全局配置文件activiti.cfg.xml配置文件信息 
  10.  * 2.获取工作流相关的服务(RepositoryService,RuntimeService, 
  11.  *    TaskService,HistoryService,FormService,ManagementService, 
  12.  *    IdentityService等) 
  13.  * 2.加载工作流文件*.bpmn20.xml信息 
  14.  *  
  15.  * 3.部署工作流 
  16.  *    部署工作流由多种方式,在以后会相继讲解 
  17.  *  
  18.  * @author longgangbai 
  19.  *  
  20.  * 2011-12-17  下午07:48:59 
  21.  */  
  22. public abstract class AbstractTest extends TestCase {  
  23.   
  24.     private ProcessEngine processEngine;  
  25.     protected String deploymentId;  
  26.     protected RepositoryService repositoryService;  
  27.     protected RuntimeService runtimeService;  
  28.     protected TaskService taskService;  
  29.     protected FormService formService;  
  30.     protected HistoryService historyService;  
  31.     protected IdentityService identityService;  
  32.     protected ManagementService managementService;  
  33.       
  34.       
  35.     /** 
  36.      * 测试用例开始初始化工作 
  37.      * 1.创建相关的工作流程对象ProcessEngine 
  38.      * 2.创建相关的服务 
  39.      * 3. 
  40.      */  
  41.     @Override  
  42.     protected void setUp() throws Exception {  
  43.         super.setUp();  
  44.         //由于ProcessEngine为线程安全性对象,整个项目可以共用一个  
  45.         if(processEngine==null) {  
  46.             //此处使用此种方法调用的activiti的配置文件为 classpath路径下的activiti.cfg.xml  
  47.             //采用的H2的数据库  
  48.             processEngine = ProcessEngines.getDefaultProcessEngine();  
  49.         }  
  50.         //获取工作流的各种服务信息  
  51.         repositoryService = processEngine.getRepositoryService();  
  52.         runtimeService = processEngine.getRuntimeService();  
  53.         taskService = processEngine.getTaskService();  
  54.         formService = processEngine.getFormService();  
  55.         historyService = processEngine.getHistoryService();  
  56.         identityService = processEngine.getIdentityService();  
  57.         managementService = processEngine.getManagementService();  
  58.         //调用扩展的初始化工作  
  59.         initialize();  
  60.           
  61.     }  
  62.       
  63.     /** 
  64.      * test销毁方法 
  65.      */  
  66.     @Override  
  67.     protected void tearDown() throws Exception {  
  68.         super.tearDown();  
  69.         destroy();  
  70.     }  
  71.       
  72.     /** 
  73.      * 便于子类的工作的初始化的扩展工作 
  74.      *  
  75.      *  
  76.      * @throws Exception 
  77.      */  
  78.     protected abstract void initialize() throws Exception;  
  79.     /** 
  80.      * 便于子类的工作的销毁的扩展工作 
  81.      *  
  82.      * @throws Exception 
  83.      */  
  84.     protected abstract void destroy() throws Exception;  
  85. }  

 

 

Java代码  收藏代码
  1. /** 
  2. package com.easyway.workflow.activiti; 
  3.  
  4.  
  5.  
  6. import java.util.HashMap; 
  7. /** 
  8.  *  
  9.  * 自定义测试的工作流的方式 
  10.  *  
  11.  * @author longgangbai 
  12.  *  
  13.  * 2011-12-17  下午10:12:54 
  14.  */  
  15. public class CustomBankAccountMoneyTaskJunit3Test  extends AbstractTest {  
  16.   
  17.     /** 
  18.      * 初始化工作流程的方法 
  19.      */  
  20.     @Override  
  21.     protected void initialize() throws Exception {  
  22.         Deployment deployment = repositoryService  
  23.         .createDeployment()  
  24.         .addClasspathResource(  
  25.                 "com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")  
  26.     .deploy();    
  27.         deploymentId = deployment.getId();  
  28.     }  
  29.       
  30.     /** 
  31.      * 销毁工作流对象的方法 
  32.      */  
  33.     @Override  
  34.     protected void destroy() throws Exception {  
  35.         repositoryService.deleteDeployment(deploymentId, true);   
  36.     }  
  37.       
  38.     /** 
  39.      * 测试工作流流程的方法 
  40.      */  
  41.     public void testSubProcess() {  
  42.         // prepare data packet  
  43.         Map<String, Object> variables = new HashMap<String, Object>();  
  44.         Map<String, Object> subVariables = new HashMap<String, Object>();  
  45.         variables.put("maxTransCount"1000000);  
  46.         variables.put("merchant""ICBC");  
  47.         variables.put("protocol""UM32");  
  48.         variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  49.         variables.put("in", subVariables);  
  50.         variables.put("out"new HashMap<String, Object>());  
  51.           
  52.         // start process instance  
  53.         //将初始化时候创建流程时设置参数  
  54.         ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);  
  55.         List<Execution> executions = runtimeService.createExecutionQuery().list();  
  56.         assertEquals(1, executions.size());  
  57.           
  58.         Execution execution = runtimeService.createExecutionQuery().singleResult();  
  59.         runtimeService.setVariable(execution.getId(), "type""receiveTask");  
  60.         //同意执行信息发送信号  
  61.         runtimeService.signal(execution.getId());  
  62.         assertEquals(1, executions.size());  
  63.           
  64.         execution = runtimeService.createExecutionQuery().list().get(0);  
  65.         assertNotNull(execution);  
  66.         //设置工作流实例对应的变量  
  67.         runtimeService.setVariable(execution.getId(), "oper""shirdrn");  
  68.             runtimeService.signal(execution.getId());  
  69.         }  
  70. }  

 

采用官方推荐Junit3实现测试如下:

Java代码  收藏代码
  1. /** 
  2. package com.easyway.workflow.activiti; 
  3.  
  4. import java.util.HashMap; 
  5. import java.util.List; 
  6. import java.util.Map; 
  7.  
  8. import org.activiti.engine.runtime.Execution; 
  9. import org.activiti.engine.runtime.ProcessInstance; 
  10. import org.activiti.engine.test.ActivitiTestCase; 
  11. import org.activiti.engine.test.Deployment; 
  12. /** 
  13.  * 手工触发执行是指,执行到流程中某个个结点后流程暂时停止运行,直到收到外部发送的信号 
  14.  * 以后,才会继续向前推进,这样情况可以更加精细地控制流程。  
  15.  * 手工触发执行  
  16.  * 通过<receiveTask>和<userTask>元素都可以实现流程的手工触发执行。  
  17.  *  
  18.  *  
  19.  * 版本单元测试采用官方推荐的Junit3方式测试Activiti工作流 
  20.  *  ,必须实现继承自ActivtiTestCase类实现的,默认activiti全局配置文件采用. 
  21.  *  activiti.cfg.xml并且测试的工作流文件的名称是测试类的名称, 
  22.  *  ActivitiTestCase 的 protected void setUp()方法调用如下 
  23.  *   deploymentId = TestHelper.annotationDeploymentSetUp(processEngine, getClass(), getName()); 
  24.  *   
  25.  *  TestHelper类调用说明如下: 
  26.  *   
  27. *    * get a resource location by convention based on a class (type) and a 
  28. *    * relative resource name. The return value will be the full classpath 
  29. *    * location of the type, plus a suffix built from the name parameter: 
  30. *    * <code>.&lt;name&gt;.bpmn20.xml</code>. 
  31. *    public static String getBpmnProcessDefinitionResource(Class< ? > type, String name) { 
  32. *     return type.getName().replace('.', '/') + "." + name + "." + BpmnDeployer.BPMN_RESOURCE_SUFFIX; 
  33. *   } 
  34. *    
  35.  * @author longgangbai 
  36.  *  
  37.  * 2011-12-17  下午09:51:13 
  38.  */  
  39. public class CheckBankAccountMoneyTaskJunit3Test extends ActivitiTestCase {  
  40.        
  41.         /** 
  42.          * 採用Junit3方式测试工作流中的方法 
  43.          */  
  44.         @Deployment(resources="com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")  
  45.         public void testSubProcess() {  
  46.             // prepare data packet  
  47.             //设置开始执行的工作流的初始化参数  
  48.             Map<String, Object> variables = new HashMap<String, Object>();  
  49.             Map<String, Object> subVariables = new HashMap<String, Object>();  
  50.             variables.put("maxTransCount"1000000);  
  51.             variables.put("merchant""ICBC");  
  52.             variables.put("protocol""UM32");  
  53.             variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  54.             variables.put("in", subVariables);  
  55.             variables.put("out"new HashMap<String, Object>());  
  56.             // start process instance  
  57.             //根据工作流ID获取工作流引擎实例  
  58.             ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);  
  59.             deploymentId=pi.getProcessDefinitionId();  
  60.             System.out.println("deploymentId="+deploymentId);  
  61.             //获取中的实例数  
  62.             List<Execution> executions = runtimeService.createExecutionQuery().list();  
  63.             assertEquals(1, executions.size());  
  64.               
  65.             //查询单个实例  
  66.             Execution execution = runtimeService.createExecutionQuery().singleResult();  
  67.             //设置运行时服务变量  
  68.             runtimeService.setVariable(execution.getId(), "type""receiveTask");  
  69.             //向特定的流程实例发送触发器执行的信号  
  70.             runtimeService.signal(execution.getId());  
  71.             assertEquals(1, executions.size());  
  72.               
  73.             execution = runtimeService.createExecutionQuery().list().get(0);  
  74.             assertNotNull(execution);  
  75.             runtimeService.setVariable(execution.getId(), "oper""shirdrn");  
  76.             runtimeService.signal(execution.getId());  
  77.         }  
  78.     }  

 

采用官方推荐Junit4实现测试如下:

Java代码  收藏代码
  1. /** 
  2. package com.easyway.workflow.activiti; 
  3.  
  4. import static org.junit.Assert.assertEquals; 
  5.  
  6. /** 
  7.  *  
  8.  *  
  9.  * 工作流模拟的业务情景如下: 
  10.  *  1.用户到银行转账业务 
  11.  *  2.银行工作人员查询用户余额 
  12.  *  3.银行工作人员帮助用户转账 
  13.  *   
  14.  * 在工作流activiti中使用Junit4测试需要使用ActivitiRule对象,创建各种对象。 
  15.  *  
  16.  * @author longgangbai 
  17.  *  
  18.  * 2011-12-17  下午11:17:35 
  19.  */  
  20. public class CheckBankAccountMoneyTaskJunit4Test {  
  21.       @Rule   
  22.       public ActivitiRule activitiRule = new ActivitiRule();   
  23.          
  24.       @Test   
  25.       @Deployment(resources="com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")  
  26.       public void ruleUsageExample() {   
  27.             //设置开始执行的工作流的初始化参数  
  28.             Map<String, Object> variables = new HashMap<String, Object>();  
  29.             Map<String, Object> subVariables = new HashMap<String, Object>();  
  30.             variables.put("maxTransCount"1000000);  
  31.             variables.put("merchant""ICBC");  
  32.             variables.put("protocol""UM32");  
  33.             variables.put("repository""10.10.38.99:/home/shirdrn/repository");  
  34.             variables.put("in", subVariables);  
  35.             variables.put("out"new HashMap<String, Object>());  
  36.             // start process instance  
  37.             //根据工作流ID获取工作流引擎实例  
  38.             RuntimeService runtimeService = activitiRule.getRuntimeService();   
  39.             ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);  
  40.             String deploymentId=pi.getProcessDefinitionId();  
  41.             System.out.println("deploymentId="+deploymentId);  
  42.             //获取中的实例数  
  43.             List<Execution> executions = runtimeService.createExecutionQuery().list();  
  44.             assertEquals(1, executions.size());  
  45.               
  46.             //查询单个实例  
  47.             Execution execution = runtimeService.createExecutionQuery().singleResult();  
  48.             //设置运行时服务变量  
  49.             runtimeService.setVariable(execution.getId(), "type""receiveTask");  
  50.             //向特定的流程实例发送触发器执行的信号  
  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.     }   

 

 运行结果如下:

Java代码  收藏代码
  1. 2011-12-18 13:08:45 org.activiti.engine.impl.ProcessEngineImpl <init>  
  2. 信息: ProcessEngine default created  
  3. 2011-12-18 13:08:45 org.activiti.engine.impl.jobexecutor.JobAcquisitionThread run  
  4. 信息: <span style="color: #ff0000;">JobAcquisitionThread starting to acquire jobs</span>  
  5. 2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy  
  6. 信息: <span style="color: #ff0000;">Processing resource com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml</span>  
  7. 2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes  
  8. 信息:<span style="color: #ff0000;"> XMLSchema currently not supported as typeLanguage</span>  
  9. 2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes  
  10. 信息: <span style="color: #ff0000;">XPath currently not supported as expressionLanguage</span>  
  11. 2011-12-18 13:08:46 com.easyway.workflow.activiti.CheckBankAccountMoneyTask execute  
  12. 信息: <span style="color: #ff0000;">根据输入参数,开始检查银行账户余额........</span>  
  13. in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=ICBC, maxTransCount=1000000, in={}, out={}}  
  14. deploymentId=BankUserTask:1:1313  
  15. 2011-12-18 13:08:46 com.easyway.workflow.activiti.CheckMerchantMoneyTask execute  
  16. 信息:<span style="color: #ff0000;"> 正在转账中.........</span>  
  17. in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=ICBC, maxTransCount=1000000, type=receiveTask, in={}, out={}}  
0 0
原创粉丝点击