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

时间:2024.4.20

工作流模拟的业务情景如下:

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=";/spec/BPMN/20100524/MODEL"; xmlns:xsi=";/2001/XMLSchema-instance";

xmlns:activiti=";http://activiti.org/bpmn";

xmlns:bpmndi=";/spec/BPMN/20100524/DI";

xmlns:omgdc=";/spec/DD/20100524/DC";

xmlns:omgdi=";/spec/DD/20100524/DI";

typeLanguage=";/2001/XMLSchema";

expressionLanguage=";/1999/XPath";

targetNamespace=";/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";

sourceRef=";receivetask1";

sourceRef=";receivetask2";

sourceRef=";receivetask1"; targetRef=";receivetask1";>;<;/sequenceFlow>; <;sequenceFlow id=";flow2"; name=";"; targetRef=";receivetask2";>;<;/sequenceFlow>; <;sequenceFlow id=";flow3"; name=";"; targetRef=";endevent1";>;<;/sequenceFlow>; <;sequenceFlow id=";flow4"; name=";";

targetRef=";endevent1";>;<;/sequenceFlow>;

<;/process>;

<;bpmndi:BPMNDiagram id=";BPMNDiagram_BankUserTask";>;

<;bpmndi:BPMNPlane bpmnElement=";BankUserTask"; id=";BPMNPlane_BankUserTask";>;

<;bpmndi:BPMNShape

id=";BPMNShape_startevent1";>;

<;omgdc:Bounds height=";35";

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

id=";BPMNShape_receivetask1";>;

<;omgdc:Bounds height=";55";

y=";210";>;<;/omgdc:Bounds>;

<;/bpmndi:BPMNShape>;

<;bpmndi:BPMNShape

id=";BPMNShape_receivetask2";>;

<;omgdc:Bounds height=";55";

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>; bpmnElement=";receivetask2"; width=";105"; x=";340"; bpmnElement=";receivetask1"; width=";105"; x=";160"; bpmnElement=";startevent1"; width=";35"; x=";76";

<;/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 { } /** * 便于子类的工作的初始化的扩展工作 * * * @throws Exception */ protected abstract void initialize() throws Exception; /** * 便于子类的工作的销毁的扩展工作 * * @throws Exception */ super.tearDown(); destroy();

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>;

runtimeService.createExecutionQuery().list();

assertEquals(1, executions.size()); //查询单个实例 Execution execution = executions = 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(),

";receiveTask";);

//向特定的流程实例发送触发器执行的信号 runtimeService.signal(execution.getId()); assertEquals(1, executions.size()); execution = runtimeService.createExecutionQuery().list().get(0); ";type";,

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官方提供的编写1财务部门填写月财务报告2股东审核月财务审计报告流程图流程配置ltxmlversionquot10quotencodingquotUTF8quotgtltdefinitions...

工作流Activiti的学习总结(三) activit数据库限制和数据库相关的配置

工作流Activiti的学习总结三activit数据库限制和数据库相关的配置数据库相关的配置在activiti中的持久化框架采用Ibatis3实现有两种方式定义activiti的数据库1通过jdbcproper...

工作流Activiti的学习总结(五) activiti的API和虚拟工作流测试

工作流Activiti的学习总结五activiti的API和虚拟工作流测试activiti的API在activiti引擎中你可以通过多种方式获取ProcessEngine对象从ProcessEngine中获取各...

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

工作流activiti自动执行任务的开发应用工作流模拟某公司请假流程情景如下1开发人员请假流程如果开发人员请假如果请假天数小于3天组长批准人事批准即可请假2如果请假大约三天需要项目经理或者产品经理批准并且项目总...

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

工作流模拟程序员面试过程情景如下1开发知识面试或者笔试2人事面试流程图流程配置Xml代码1ltxmlversionquot10quotencodingquotUTF8quotgt2ltdefinitionsxm...

工作流Activiti的学习总结(四)Spring和Activiti的整合配置讲解

工作流Activiti的学习总结(四)Spring和Activiti的整合配置讲解Spring和Activiti的整合:在Spring和Activiti的整合中ProcessEngineFactoryBean成…

工作流Activiti的学习总结(二)activiti中ProcessEngine的创建和数据库表命名规则

工作流Activiti的学习总结(二)activiti中ProcessEngine的创建和数据库表命名规则数据库表命名规则:Activiti工作流引擎的数据库表中的表名称都是以ACT_.第二部分两个字母表示表的…

Activiti工作流对象关系及表结构

Activiti数据表结构和核心对象关系西安创富电子科技有限公司二一三年九月西安创富电子科技有限公司Activiti数据表结构和核心对象关系版本历史西安创富电子科技有限公司Activiti数据表结构和核心对象关...

用activiti 工作流 实现简单的请假 附带源码

用activiti工作流实现简单的请假附带源码用activiti工作流实现简单的请假附带源码新建一个Maven项目项目结构pomxmlhtmlviewplaincopy1ltspangtprojectxmlns...

javascript学习总结

Javascrip基础与实践教程电子工业出版社一javascrip语言概述1ECMAScript是许多软件厂商对JavaScript的统一标准2服务器端和客户端JavaScript共享相同的核心语言但也有些不同...

javascript学习总结

javascript学习总结1JavaScript中的对象分为3种1JavaScript的内置对象常用的有DateArrayStringMath对象这些都是经常会用到的一定要掌握好2文档对象模型Document...

javascript学习总结

一JavaScriptJavaScript被设计用来向HTML页面添加交互行为JavaScript是一种脚本语言脚本语言是一种轻量级的编程语言JavaScript由数行可执行计算机代码组成JavaScript通...

工作流activiti的学习总结(15篇)