Activiti 5.3:子流程(subProcess)

来源:互联网 发布:方正字体 for mac 编辑:程序博客网 时间:2024/05/16 17:27

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

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

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

 

内嵌子流程

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

 

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

<?xml version="1.0" encoding="UTF-8"?><definitions id="definitions"    xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn"    targetNamespace="Examples">    <process id="MySubprocess" name="My Subprocess">        <startEvent id="theStart" />        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="subProcess" />                 <subProcess id="subProcess">            <startEvent id="subProcessStart" />            <sequenceFlow id="flow2" sourceRef="subProcessStart" targetRef="subProcessFork" />            <parallelGateway id="subProcessFork" />            <sequenceFlow id="flow3" sourceRef="subProcessFork" targetRef="task1" />            <sequenceFlow id="flow4" sourceRef="subProcessFork" targetRef="task2" />            <userTask id="task1" name="Check bank" activiti:candidateGroups="engineering">                <extensionElements>                    <activiti:taskListener event="complete"                        class="org.shirdrn.workflow.activiti.subprocess.CheckBankTask" />                </extensionElements>            </userTask>            <sequenceFlow id="flow5" sourceRef="task1" targetRef="subProcessJoin" />            <userTask id="task2" name="Investigate software" activiti:candidateGroups="engineering" >                <extensionElements>                    <activiti:taskListener event="complete"                        class="org.shirdrn.workflow.activiti.subprocess.CheckMerchantTask" />                </extensionElements>            </userTask>            <sequenceFlow id="flow6" sourceRef="task2" targetRef="subProcessJoin" />            <parallelGateway id="subProcessJoin" />            <sequenceFlow id="flow7" sourceRef="subProcessJoin" targetRef="subProcessEnd" />            <endEvent id="subProcessEnd" />        </subProcess>         <sequenceFlow id="flow10" sourceRef="subProcess" targetRef="taskAfterSubProcess" />        <userTask id="taskAfterSubProcess" name="Collect message" activiti:candidateGroups="engineering" >            <extensionElements>                    <activiti:taskListener event="complete"                        class="org.shirdrn.workflow.activiti.subprocess.CollectMessageTask" />            </extensionElements>        </userTask>        <sequenceFlow id="flow11" sourceRef="taskAfterSubProcess" targetRef="theEnd" />        <endEvent id="theEnd" />    </process> </definitions>

?

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

package org.shirdrn.workflow.activiti.subprocess; import java.util.HashMap;import java.util.logging.Logger; import org.activiti.engine.delegate.DelegateTask;import org.activiti.engine.impl.pvm.delegate.TaskListener; public class CheckBankTask implements TaskListener {     private final Logger log = Logger.getLogger(CheckBankTask.class.getName());         @SuppressWarnings("unchecked")    public void notify(DelegateTask delegateTask) {        log.info("i am CheckBankTask.");        System.out.println("in : " + delegateTask.getVariables());        ((HashMap<String, Object>)delegateTask.getVariables().get("in")).put("next", "CheckBankTask");        ((HashMap<String, Object>)delegateTask.getVariables().get("out")).put("reponse", "subprocess:CheckBankTask->CheckMerchantTask");    }}

package org.shirdrn.workflow.activiti.subprocess; import java.util.HashMap; public class CheckMerchantTask implements TaskListener {     private final Logger log = Logger.getLogger(CheckMerchantTask.class.getName());         @SuppressWarnings("unchecked")    public void notify(DelegateTask delegateTask) {        log.info("i am CheckMerchantTask.");        System.out.println("in : " + delegateTask.getVariables());        ((HashMap<String, Object>)delegateTask.getVariables().get("in")).put("previous", "CheckMerchantTask");    }}

package org.shirdrn.workflow.activiti.subprocess; import java.util.Map; public class CollectMessageTask implements TaskListener {     private final Logger log = Logger.getLogger(CollectMessageTask.class.getName());         @SuppressWarnings("unchecked")    public void notify(DelegateTask delegateTask) {        log.info("i am CollectMessageTask.");        System.out.println("out : " + (Map<String, Object>)delegateTask.getVariables().get("out"));        System.out.println("all : " + delegateTask.getVariables());    }}

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

package org.shirdrn.workflow.activiti.subprocess; import java.util.HashMap;import java.util.List;import java.util.Map; import org.activiti.engine.repository.Deployment;import org.activiti.engine.runtime.ProcessInstance;import org.activiti.engine.task.Task;import org.shirdrn.workflow.activiti.AbstractTest; /** * <a href="http://my.oschina.net/arthor" class="referer" target="_blank">@author</a> shirdrn */public class MySubProcessTest extends AbstractTest {     @Override    protected void initialize() throws Exception {        Deployment deployment = repositoryService        .createDeployment()        .addClasspathResource(                "diagrams/SubProcessTest.MySubprocess.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", new 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("MySubprocess", variables);                 // enter subprocess        List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc().list();        assertEquals(2, tasks.size());                 for(Task task : tasks) {            taskService.complete(task.getId());        }                 // leave subprocess        Task collectTask = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();        assertEquals("Collect message", collectTask.getName());                 Map<String, Object> taskVariables = new HashMap<String, Object>();        taskVariables.put("att", "anything you need");        taskService.setVariable(collectTask.getId(), "oper", "shirdrn");        taskService.complete(collectTask.getId(), taskVariables);    } }

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

2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CheckBankTask notify信息: i am CheckBankTask.in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000, in={}, out={}}2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CheckMerchantTask notify信息: i am CheckMerchantTask.in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000, in={next=CheckBankTask}, out={reponse=subprocess:CheckBankTask->CheckMerchantTask}}2011-3-24 17:36:36 org.shirdrn.workflow.activiti.subprocess.CollectMessageTask notify信息: i am CollectMessageTask.out : {reponse=subprocess:CheckBankTask->CheckMerchantTask}all : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], oper=shirdrn, att=anything you need, maxTransCount=1000000, in={previous=CheckMerchantTask, next=CheckBankTask}, out={reponse=subprocess:CheckBankTask->CheckMerchantTask}}

调用子流程

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

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

<?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="CheckSubprocess" name="CheckSubprocess">    <startEvent id="startevent4" name="Start"></startEvent>    <serviceTask id="servicetask4" name="Check User" activiti:class="org.shirdrn.workflow.activiti.subprocess.BusinessCheck"></serviceTask>    <endEvent id="endevent4" name="End"></endEvent>    <sequenceFlow id="flow7" name="" sourceRef="startevent4" targetRef="servicetask4"></sequenceFlow>    <sequenceFlow id="flow8" name="" sourceRef="servicetask4" targetRef="endevent4"></sequenceFlow>  </process></definitions>

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

package org.shirdrn.workflow.activiti.subprocess; import java.util.logging.Logger; import org.activiti.engine.delegate.DelegateExecution;import org.activiti.engine.delegate.JavaDelegate; public class BusinessCheck implements JavaDelegate {         private static final Logger log = Logger.getLogger(BusinessCheck.class.getName());         @Override    public void execute(DelegateExecution execution) throws Exception {        // varOutFromMainprocess<->varInSubprocess        String varInSubprocess = (String)execution.getVariable("varInSubprocess");        log.info("in subprocess get(varInSubprocess): " + varInSubprocess);                 log.info("variavles=" + execution.getVariables());        execution.setVariable("s:bc", "Subprocess:BusinessCheck");        log.info("I am BusinessCheck in subprocess.");                   execution.setVariable("varInSubprocess", "BBBB");        log.info("in subprocess set(varInSubprocess): " + varInSubprocess);    }}

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

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

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

<?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="Mainprocess" name="Main Process">        <startEvent id="startevent1" name="Start"></startEvent>        <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>        <serviceTask id="servicetask1" name="System Initialization" activiti:class="org.shirdrn.workflow.activiti.subprocess.Initialization"></serviceTask>        <sequenceFlow id="flow2" name="" sourceRef="servicetask1" targetRef="callSubprocess"></sequenceFlow>        <callActivity id="callSubprocess" calledElement="CheckSubprocess" >           <extensionElements>                   <activiti:in source="varOutFromMainprocess" target="varInSubprocess" />                   <activiti:out source="varInSubprocess" target="varOutFromSubprocess" />           </extensionElements>         </callActivity>        <sequenceFlow id="flow3" name="" sourceRef="callSubprocess" targetRef="servicetask2"></sequenceFlow>        <serviceTask id="servicetask2" name="Do Transaction" activiti:class="org.shirdrn.workflow.activiti.subprocess.DoTransaction"></serviceTask>        <sequenceFlow id="flow4" name="" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow>        <endEvent id="endevent1" name="End"></endEvent>    </process></definitions>

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

<callActivity id="callSubprocess" calledElement="CheckSubprocess" >   <extensionElements>       <activiti:in source="varOutFromMainprocess" target="varInSubprocess" />       <activiti:out source="varInSubprocess" target="varOutFromSubprocess" />   </extensionElements> </callActivity>

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

package org.shirdrn.workflow.activiti.subprocess; import java.util.logging.Logger; public class Initialization implements JavaDelegate {         private static final Logger log = Logger.getLogger(Initialization.class.getName());         @Override    public void execute(DelegateExecution execution) throws Exception {        log.info("variavles=" + execution.getVariables());        execution.setVariable("m:i", "Mainprocess:Initialization");        log.info("I am Initialization in mainprocess.");                 execution.setVariable("varOutFromMainprocess", "AAAA");        log.info("in mainprocess set(varOutFromMainprocess): " + execution.getVariable("varOutFromMainprocess"));    }}

package org.shirdrn.workflow.activiti.subprocess; import java.util.logging.Logger; public class DoTransaction implements JavaDelegate {         private static final Logger log = Logger.getLogger(DoTransaction.class.getName());         @Override    public void execute(DelegateExecution execution) throws Exception {        // varInSubprocess<->varOutFromSubprocess        String varOutFromSubprocess = (String)execution.getVariable("varOutFromSubprocess");        log.info("in mainprocess get(varOutFromSubprocess): " + varOutFromSubprocess);                 log.info("variavles=" + execution.getVariables());        execution.setVariable("m:dt", "Mainprocess:DoTransaction");        log.info("I am DoTransaction in mainprocess.");    }}

?

?

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

package org.shirdrn.workflow.activiti.subprocess; import java.util.HashMap;import java.util.Map; import org.activiti.engine.repository.Deployment;import org.activiti.engine.runtime.ProcessInstance;import org.shirdrn.workflow.activiti.AbstractTest; /** * <a href="http://my.oschina.net/arthor" class="referer" target="_blank">@author</a> shirdrn */public class MainprocessTest extends AbstractTest {     @Override    protected void initialize() throws Exception {        Deployment deployment = repositoryService        .createDeployment()        .addClasspathResource(                "diagrams/Subprocess.Check.bpmn20.xml")        .deploy();          deploymentIdList.add(deployment.getId());                 deployment = repositoryService        .createDeployment()        .addClasspathResource(                "diagrams/Subprocess.Mainprocess.bpmn20.xml")        .deploy();          deploymentIdList.add(deployment.getId());    }     @Override    protected void destroy() throws Exception {        for(String deployment : deploymentIdList) {            repositoryService.deleteDeployment(deployment, 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("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("Mainprocess", variables);                 assertEquals(true, pi.isEnded());    } }


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

2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute信息: variavles={protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, in={}, out={}}2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute信息: I am Initialization in mainprocess.2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.Initialization execute信息: in mainprocess set(varOutFromMainprocess): AAAA2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute信息: in subprocess get(varInSubprocess): AAAA2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute信息: variavles={varInSubprocess=AAAA}2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute信息: I am BusinessCheck in subprocess.2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute信息: in subprocess set(varInSubprocess): AAAA2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute信息: in mainprocess get(varOutFromSubprocess): BBBB2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute信息: variavles={protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, varOutFromSubprocess=BBBB, varOutFromMainprocess=AAAA, in={}, out={}, m:i=Mainprocess:Initialization}2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute信息: I am DoTransaction in mainprocess.


?
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 周岁宝宝大便出血了怎么办 十一个月宝宝大便干燥怎么办 8个月宝宝大便干燥怎么办 7个月宝宝大便干燥怎么办 11个月宝宝大便干燥怎么办 9个月宝宝大便干燥怎么办 10个月宝宝大便干燥怎么办 宝宝两天没拉粑粑了怎么办 小学闺蜜嫉妒我怎么办 三年级孩子对应用题理解很差怎么办 我嫉妒我的朋友怎么办 嫉妒同学比我好怎么办 宝宝生在家里了怎么办 在家不小心生了怎么办 葫芦干了有黑点怎么办 单位费用发票丢失了怎么办 1岁宝宝太调皮了怎么办 孩子和同学打架家长该怎么办 孩子被大人打了怎么办 小孩不跟大人沟通怎么办 2岁小朋友爱动手怎么办 小班爱动手的小朋友怎么办 宝宝对小朋友不友好爱动手怎么办 小孩子上幼儿园爱打人怎么办 小孩被别人打了怎么办 1岁幼儿爱打人怎么办 作为幼小朋友打人老师怎么办 2岁半小朋友喜欢打人怎么办 2岁宝宝脾气大怎么办 4月小孩爱动怎么办 一岁宝宝老打人怎么办 1岁宝宝爱打人怎么办 3岁宝宝喜欢抓人怎么办 宝宝喜欢打人怎么办2岁 1岁宝宝动手打人怎么办 孩子总打人总哭怎么办 小孩出现夜惊家人怎么办 小孩不原跟家人沟通怎么办 孩子字写得难看怎么办 孩子上一年级不认识字怎么办 二年级孩子语文差怎么办