`
longgangbai
  • 浏览: 7348585 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

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

 

本文讲解ReceiveTask方式实现:

配置如下:

 

   <receiveTask id="receivetask2" name="开始转账">
      <extensionElements>
         <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckMerchantMoneyTask"></activiti:executionListener>
      </extensionElements>
    </receiveTask>

 

 

流程图如下:

 

流程配置如下:

 

<?xml version="1.0" encoding="UTF-8"?>
<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">
  <process id="BankUserTask" name="BankUserTask">
    <documentation>Place documentation for the 'BankUserTask' process here.</documentation>
    <startEvent id="startevent1" name="准备转账业务"></startEvent>
    <endEvent id="endevent1" name="转账结束"></endEvent>
    <receiveTask id="receivetask1" name="检查账户余额">
     <extensionElements>
        <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckBankAccountMoneyTask"/>
     </extensionElements>
    </receiveTask>
    <receiveTask id="receivetask2" name="开始转账">
      <extensionElements>
         <activiti:executionListener event="start" class="com.easyway.workflow.activiti.CheckMerchantMoneyTask"></activiti:executionListener>
      </extensionElements>
    </receiveTask>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="receivetask1"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="receivetask1" targetRef="receivetask2"></sequenceFlow>
    <sequenceFlow id="flow3" name="" sourceRef="receivetask2" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow4" name="" sourceRef="receivetask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_BankUserTask">
    <bpmndi:BPMNPlane bpmnElement="BankUserTask" id="BPMNPlane_BankUserTask">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35" width="35" x="76" y="218"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35" width="35" x="590" y="220"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="receivetask1" id="BPMNShape_receivetask1">
        <omgdc:Bounds height="55" width="105" x="160" y="210"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="receivetask2" id="BPMNShape_receivetask2">
        <omgdc:Bounds height="55" width="105" x="340" y="210"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="111" y="235"></omgdi:waypoint>
        <omgdi:waypoint x="160" y="237"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="265" y="237"></omgdi:waypoint>
        <omgdi:waypoint x="340" y="237"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="445" y="237"></omgdi:waypoint>
        <omgdi:waypoint x="590" y="237"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="265" y="237"></omgdi:waypoint>
        <omgdi:waypoint x="212" y="338"></omgdi:waypoint>
        <omgdi:waypoint x="385" y="338"></omgdi:waypoint>
        <omgdi:waypoint x="607" y="338"></omgdi:waypoint>
        <omgdi:waypoint x="607" y="255"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

 

 

代码实现如下:

 

 

/**
package com.easyway.workflow.activiti;
import java.util.HashMap;
/**
 * 银行工作人员开始查询用户余额的事件
 * 
 * @author longgangbai
 * 
 * 2011-12-17  上午09:37:50
 */
public class CheckBankAccountMoneyTask implements JavaDelegate {

	private final Logger log = Logger.getLogger(CheckBankAccountMoneyTask.class.getName());

	@SuppressWarnings("unchecked")
	@Override
	public void execute(DelegateExecution execution) throws Exception {
		log.info("根据输入参数,开始检查银行账户余额........");
		System.out.println("in : " + execution.getVariables());
		((HashMap<String, Object>)execution.getVariables().get("in")).put("next", "CheckBankTask");
		((HashMap<String, Object>)execution.getVariables().get("out")).put("reponse", "subprocess:CheckBankReceiveTask->CheckMerchantReceiveTask");		
	}
}

 

 

package com.easyway.workflow.activiti;

import java.util.HashMap;
/**
 * 
 * 银行工作人员开始转账过程
 * @author longgangbai
 * 
 * 2011-12-17  下午09:39:14
 */
public class CheckMerchantMoneyTask implements JavaDelegate {

	private final Logger log = Logger.getLogger(CheckMerchantMoneyTask.class.getName());
	
	@SuppressWarnings("unchecked")
	@Override
	public void execute(DelegateExecution execution) throws Exception {
		log.info("正在转账中.........");
		System.out.println("in : " + execution.getVariables());
		((HashMap<String, Object>)execution.getVariables().get("in")).put("previous", "CheckMerchantReceiveTask");
	}
}

 

 

package com.easyway.workflow.activiti;


import junit.framework.TestCase;
/**
 * 主要是在测试之前做一些初始化工作,主要包括流程引擎实例
 * 的构建,及其流程提供的基本服务。
 * 目的:让开发者熟悉工作流使用过程使用的几个步骤
 * 1.加载相关的工作流全局配置文件activiti.cfg.xml配置文件信息
 * 2.获取工作流相关的服务(RepositoryService,RuntimeService,
 *    TaskService,HistoryService,FormService,ManagementService,
 *    IdentityService等)
 * 2.加载工作流文件*.bpmn20.xml信息
 * 
 * 3.部署工作流
 *    部署工作流由多种方式,在以后会相继讲解
 * 
 * @author longgangbai
 * 
 * 2011-12-17  下午07:48:59
 */
public abstract class AbstractTest extends TestCase {

	private ProcessEngine processEngine;
	protected String deploymentId;
	protected RepositoryService repositoryService;
	protected RuntimeService runtimeService;
	protected TaskService taskService;
	protected FormService formService;
	protected HistoryService historyService;
	protected IdentityService identityService;
	protected ManagementService managementService;
	
	
	/**
	 * 测试用例开始初始化工作
	 * 1.创建相关的工作流程对象ProcessEngine
	 * 2.创建相关的服务
	 * 3.
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		//由于ProcessEngine为线程安全性对象,整个项目可以共用一个
		if(processEngine==null) {
			//此处使用此种方法调用的activiti的配置文件为 classpath路径下的activiti.cfg.xml
			//采用的H2的数据库
			processEngine = ProcessEngines.getDefaultProcessEngine();
		}
		//获取工作流的各种服务信息
		repositoryService = processEngine.getRepositoryService();
		runtimeService = processEngine.getRuntimeService();
		taskService = processEngine.getTaskService();
		formService = processEngine.getFormService();
		historyService = processEngine.getHistoryService();
		identityService = processEngine.getIdentityService();
		managementService = processEngine.getManagementService();
		//调用扩展的初始化工作
		initialize();
		
	}
	
	/**
	 * test销毁方法
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
		destroy();
	}
	
	/**
	 * 便于子类的工作的初始化的扩展工作
	 * 
	 * 
	 * @throws Exception
	 */
	protected abstract void initialize() throws Exception;
	/**
	 * 便于子类的工作的销毁的扩展工作
	 * 
	 * @throws Exception
	 */
	protected abstract void destroy() throws Exception;
}

 

 

/**
package com.easyway.workflow.activiti;



import java.util.HashMap;
/**
 * 
 * 自定义测试的工作流的方式
 * 
 * @author longgangbai
 * 
 * 2011-12-17  下午10:12:54
 */
public class CustomBankAccountMoneyTaskJunit3Test  extends AbstractTest {

	/**
	 * 初始化工作流程的方法
	 */
	@Override
	protected void initialize() throws Exception {
		Deployment deployment = repositoryService
		.createDeployment()
		.addClasspathResource(
				"com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")
	.deploy();	
		deploymentId = deployment.getId();
	}
	
	/**
	 * 销毁工作流对象的方法
	 */
	@Override
	protected void destroy() throws Exception {
		repositoryService.deleteDeployment(deploymentId, true);	
	}
	
	/**
	 * 测试工作流流程的方法
	 */
	public void testSubProcess() {
		// prepare data packet
		Map<String, Object> variables = new HashMap<String, Object>();
		Map<String, Object> subVariables = new HashMap<String, Object>();
		variables.put("maxTransCount", 1000000);
		variables.put("merchant", "ICBC");
		variables.put("protocol", "UM32");
		variables.put("repository", "10.10.38.99:/home/shirdrn/repository");
		variables.put("in", subVariables);
		variables.put("out", new HashMap<String, Object>());
		
		// start process instance
		//将初始化时候创建流程时设置参数
		ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);
		List<Execution> executions = runtimeService.createExecutionQuery().list();
		assertEquals(1, executions.size());
		
		Execution execution = runtimeService.createExecutionQuery().singleResult();
		runtimeService.setVariable(execution.getId(), "type", "receiveTask");
		//同意执行信息发送信号
		runtimeService.signal(execution.getId());
		assertEquals(1, executions.size());
		
		execution = runtimeService.createExecutionQuery().list().get(0);
		assertNotNull(execution);
		//设置工作流实例对应的变量
		runtimeService.setVariable(execution.getId(), "oper", "shirdrn");
			runtimeService.signal(execution.getId());
		}
}

 

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

/**
package com.easyway.workflow.activiti;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.ActivitiTestCase;
import org.activiti.engine.test.Deployment;
/**
 * 手工触发执行是指,执行到流程中某个个结点后流程暂时停止运行,直到收到外部发送的信号
 * 以后,才会继续向前推进,这样情况可以更加精细地控制流程。 
 * 手工触发执行 
 * 通过<receiveTask>和<userTask>元素都可以实现流程的手工触发执行。 
 * 
 * 
 * 版本单元测试采用官方推荐的Junit3方式测试Activiti工作流
 *  ,必须实现继承自ActivtiTestCase类实现的,默认activiti全局配置文件采用.
 *  activiti.cfg.xml并且测试的工作流文件的名称是测试类的名称,
 *  ActivitiTestCase 的 protected void setUp()方法调用如下
 *   deploymentId = TestHelper.annotationDeploymentSetUp(processEngine, getClass(), getName());
 *  
 *  TestHelper类调用说明如下:
 *  
*    * get a resource location by convention based on a class (type) and a
*    * relative resource name. The return value will be the full classpath
*    * location of the type, plus a suffix built from the name parameter:
*    * <code>.&lt;name&gt;.bpmn20.xml</code>.
*    public static String getBpmnProcessDefinitionResource(Class< ? > type, String name) {
*     return type.getName().replace('.', '/') + "." + name + "." + BpmnDeployer.BPMN_RESOURCE_SUFFIX;
*   }
*   
 * @author longgangbai
 * 
 * 2011-12-17  下午09:51:13
 */
public class CheckBankAccountMoneyTaskJunit3Test extends ActivitiTestCase {
	 
	    /**
	     * 採用Junit3方式测试工作流中的方法
	     */
	    @Deployment(resources="com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")
		public void testSubProcess() {
			// prepare data packet
	    	//设置开始执行的工作流的初始化参数
			Map<String, Object> variables = new HashMap<String, Object>();
			Map<String, Object> subVariables = new HashMap<String, Object>();
			variables.put("maxTransCount", 1000000);
			variables.put("merchant", "ICBC");
			variables.put("protocol", "UM32");
			variables.put("repository", "10.10.38.99:/home/shirdrn/repository");
			variables.put("in", subVariables);
			variables.put("out", new HashMap<String, Object>());
			// start process instance
			//根据工作流ID获取工作流引擎实例
			ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);
			deploymentId=pi.getProcessDefinitionId();
			System.out.println("deploymentId="+deploymentId);
            //获取中的实例数
			List<Execution> executions = runtimeService.createExecutionQuery().list();
			assertEquals(1, executions.size());
			
			//查询单个实例
			Execution execution = runtimeService.createExecutionQuery().singleResult();
			//设置运行时服务变量
			runtimeService.setVariable(execution.getId(), "type", "receiveTask");
		    //向特定的流程实例发送触发器执行的信号
			runtimeService.signal(execution.getId());
			assertEquals(1, executions.size());
			
			execution = runtimeService.createExecutionQuery().list().get(0);
			assertNotNull(execution);
			runtimeService.setVariable(execution.getId(), "oper", "shirdrn");
			runtimeService.signal(execution.getId());
		}
	}

 

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

/**
package com.easyway.workflow.activiti;

import static org.junit.Assert.assertEquals;

/**
 * 
 * 
 * 工作流模拟的业务情景如下:
 *  1.用户到银行转账业务
 *  2.银行工作人员查询用户余额
 *  3.银行工作人员帮助用户转账
 *  
 * 在工作流activiti中使用Junit4测试需要使用ActivitiRule对象,创建各种对象。
 * 
 * @author longgangbai
 * 
 * 2011-12-17  下午11:17:35
 */
public class CheckBankAccountMoneyTaskJunit4Test {
	  @Rule 
	  public ActivitiRule activitiRule = new ActivitiRule(); 
	   
	  @Test 
	  @Deployment(resources="com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml")
	  public void ruleUsageExample() { 
			//设置开始执行的工作流的初始化参数
			Map<String, Object> variables = new HashMap<String, Object>();
			Map<String, Object> subVariables = new HashMap<String, Object>();
			variables.put("maxTransCount", 1000000);
			variables.put("merchant", "ICBC");
			variables.put("protocol", "UM32");
			variables.put("repository", "10.10.38.99:/home/shirdrn/repository");
			variables.put("in", subVariables);
			variables.put("out", new HashMap<String, Object>());
			// start process instance
			//根据工作流ID获取工作流引擎实例
			RuntimeService runtimeService = activitiRule.getRuntimeService(); 
			ProcessInstance pi = runtimeService.startProcessInstanceByKey("BankUserTask", variables);
			String deploymentId=pi.getProcessDefinitionId();
			System.out.println("deploymentId="+deploymentId);
		    //获取中的实例数
			List<Execution> executions = runtimeService.createExecutionQuery().list();
			assertEquals(1, executions.size());
			
			//查询单个实例
			Execution execution = runtimeService.createExecutionQuery().singleResult();
			//设置运行时服务变量
			runtimeService.setVariable(execution.getId(), "type", "receiveTask");
		    //向特定的流程实例发送触发器执行的信号
			runtimeService.signal(execution.getId());
			assertEquals(1, executions.size());
			
			execution = runtimeService.createExecutionQuery().list().get(0);
			assertNotNull(execution);
			runtimeService.setVariable(execution.getId(), "oper", "shirdrn");
			runtimeService.signal(execution.getId());
	  } 
	} 

 

 运行结果如下:

2011-12-18 13:08:45 org.activiti.engine.impl.ProcessEngineImpl <init>
信息: ProcessEngine default created
2011-12-18 13:08:45 org.activiti.engine.impl.jobexecutor.JobAcquisitionThread run
信息: JobAcquisitionThread starting to acquire jobs
2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy
信息: Processing resource com/easyway/workflow/activiti/BankUserTaskActiviti.bpmn20.xml
2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes
信息: XMLSchema currently not supported as typeLanguage
2011-12-18 13:08:45 org.activiti.engine.impl.bpmn.parser.BpmnParse parseDefinitionsAttributes
信息: XPath currently not supported as expressionLanguage
2011-12-18 13:08:46 com.easyway.workflow.activiti.CheckBankAccountMoneyTask execute
信息: 根据输入参数,开始检查银行账户余额........
in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=ICBC, maxTransCount=1000000, in={}, out={}}
deploymentId=BankUserTask:1:1313
2011-12-18 13:08:46 com.easyway.workflow.activiti.CheckMerchantMoneyTask execute
信息: 正在转账中.........
in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=ICBC, maxTransCount=1000000, type=receiveTask, in={}, out={}}

 

分享到:
评论

相关推荐

    工作流Activiti的学习总结(八)Activiti自动执行的应用

    标题中的“工作流Activiti的学习总结(八)Activiti自动执行的应用”表明本文将探讨如何在Activiti工作流引擎中实现任务的自动化执行。Activiti是一个开源的工作流和业务流程管理(BPM)系统,广泛应用于企业级应用...

    工作流Activiti5学习总结

    【工作流Activiti5学习总结】 工作流管理系统(Workflow Management System, WfMS)是企业信息化建设中的重要组成部分,它负责协调和管理业务流程。Activiti5是一款开源的工作流引擎,由Alfresco公司开发,它基于...

    工作流activiti学习代码

    工作流Activiti是一种开源的工作流引擎,用于在企业应用程序中实现业务流程自动化。它由Alfresco Software开发,旨在提供灵活、可扩展且易于使用的流程管理解决方案。在本"工作流Activiti学习代码"资源中,我们将...

    工作流Activiti的学习总结(十二) activiti官方十分钟快速学习

    在本篇博客“工作流Activiti的学习总结(十二)activiti官方十分钟快速学习”中,作者分享了关于Activiti工作流引擎的快速学习经验。Activiti是一个开源的、基于Java的企业级工作流引擎,它被广泛应用于自动化业务...

    activiti工作流PPT

    **正文** ...总结来说,了解并熟练掌握Activiti的常用API对于任何希望实现高效工作流管理的开发者都至关重要。通过学习这个PPT,你将能够更好地理解和应用Activiti,从而提升你的业务流程自动化能力。

    activiti工作流学习总结

    总的来说,这篇“activiti工作流学习总结”旨在帮助读者全面掌握Activiti的工作流程、设计方法以及实际操作技巧,对于希望在企业级应用中实施工作流管理的开发者具有很高的参考价值。通过深入学习和实践,不仅可以...

    Activiti工作流示例Activiti Demo(带完整源码)非常实用

    Activiti是一款开源的工作流引擎,它基于模型驱动的架构(MDA),专为现代企业应用程序设计,用于处理业务流程自动化。这个"Activiti工作流示例Activiti Demo"提供了完整的源代码,帮助开发者深入理解并实际操作...

    工作流activiti实战项目源码

    本项目“工作流activiti实战项目源码”提供了使用Activiti实现工作流的实例,适合开发者进行学习和实践。 在深入理解这个项目之前,我们先来了解一下Activiti的基本概念和功能: 1. **什么是Activiti**:Activiti ...

    Activiti工作流面试相关知识

    Activiti工作流引擎是一款开源的企业级业务流程管理(BPM)和工作流系统,它为组织提供了一种灵活、可扩展的方式来设计、执行和管理业务流程。在面试中,了解Activiti的核心服务对于理解其工作原理和实际应用至关...

    activiti工作流(超详细)

    activiti工作流文档,超详细,从0基础开始入门,包括数据库介绍、核心api等介绍,满足日常开发所需

    工作流Activiti的学习总结(十)Activiti手动执行的应用(UserTask)

    在本篇博文中,我们将深入探讨工作流引擎Activiti中手动执行任务(UserTask)的应用。Activiti是一款开源的工作流和业务流程管理(BPM)系统,它提供了强大的流程定义、执行和监控能力。在这个学习总结中,我们将专注于...

    工作流activiti源码案例

    工作流Activiti是一个开源的工作流引擎,用于在Java应用程序中实现业务流程自动化。它提供了一套全面的工具和API,使开发人员能够轻松地设计、部署和管理业务流程。在这个"工作流activiti源码案例"中,我们可以深入...

    Activiti工作流详细讲解完整教程.pdf

    根据提供的文件信息,我们可以深入探讨Activiti工作流框架的相关知识点。 ### Activiti工作流框架概述 Activiti工作流框架是一款由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架。它以其灵活性、易用...

    工作流Activiti的学习总结Activiti5.6和Spring3.03整合

    总结起来,Activiti 5.6与Spring 3.03的整合提供了一种高效的方式来建模和执行业务流程,如模拟程序员的面试过程。通过XML配置,我们可以定义复杂的流程逻辑,并结合Spring的特性进行灵活的控制和管理。这种整合使得...

    Activiti工作流学习文件

    ### Activiti工作流实战学习知识点概览 #### 一、工作流与工作流引擎 - **工作流**:指在计算机系统中通过特定的模型表示和实现的工作流程逻辑与规则。这种模型使得文档、信息或任务能够在多个参与者之间按照预定...

    疯狂Workflow讲义 基于Activiti的工作流应用开发 配套源码

    《疯狂Workflow讲义》是一本深入探讨基于Activiti工作流应用开发的专业书籍,其配套源码为学习者提供了丰富的实践素材。Activiti是一款强大的、开源的企业级工作流引擎,广泛应用于业务流程自动化和管理工作流。在...

    工作流activiti-6.0.0.zip

    Activiti 是一个开源的工作流引擎,它主要用于自动化业务流程。这个"工作流activiti-6.0.0.zip"文件包含的是Activiti 6.0.0版本的完整包,通常包括源代码、文档、库文件和其他必要的组件,用于开发和部署基于...

Global site tag (gtag.js) - Google Analytics