Activiti 5.3:子流程(subProcess)
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 {@Overrideprotected void initialize() throws Exception {Deployment deployment = repositoryService.createDeployment().addClasspathResource("diagrams/SubProcessTest.MySubprocess.bpmn20.xml").deploy(); deploymentId = deployment.getId();}@Overrideprotected void destroy() throws Exception {repositoryService.deleteDeployment(deploymentId, true); }public void testSubProcess() {// prepare data packetMap<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 instanceProcessInstance pi = runtimeService.startProcessInstanceByKey("MySubprocess", variables);// enter subprocessList<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc().list();assertEquals(2, tasks.size());for(Task task : tasks) {taskService.complete(task.getId());}// leave subprocessTask 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,如下所示:
上面的流程定義,和通常定義流程的方式是相同的。流程中,對應的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());@Overridepublic void execute(DelegateExecution execution) throws Exception {// varOutFromMainprocess<->varInSubprocessString 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,如下所示:
需要說明的是,對于主流程與子流程之間進行數據交換,需要在<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());@Overridepublic 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());@Overridepublic void execute(DelegateExecution execution) throws Exception {// varInSubprocess<->varOutFromSubprocessString 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.");} } ? ?
實現的測試用例,代碼如下所示:
代碼中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): AAAA 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.BusinessCheck execute 信息: in subprocess get(varInSubprocess): AAAA 2011-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): AAAA 2011-3-24 17:52:13 org.shirdrn.workflow.activiti.subprocess.DoTransaction execute 信息: in mainprocess get(varOutFromSubprocess): BBBB 2011-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.
? 新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!
總結
以上是生活随笔為你收集整理的Activiti 5.3:子流程(subProcess)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql查询优化——中间表方法优化co
- 下一篇: nyoj 945 Just do it(