用Activiti/Flowable跑一遍就懂了:BPMN2.0四种网关的Java代码与执行日志全解析
深入解析BPMN2.0四大网关Activiti/Flowable实战与日志分析在业务流程管理领域BPMN2.0标准中的网关(Gateways)是控制流程走向的核心元素。本文将基于Spring Boot环境通过Activiti/Flowable引擎的实际代码演示结合执行日志和数据库表变化深度剖析排他网关、并行网关、包容网关和基于事件网关的工作原理。不同于单纯的概念讲解我们将从工程实践角度用可复现的测试案例展示每种网关的分支合并行为。1. 环境准备与基础配置在开始网关实验前我们需要准备一个标准的Spring Boot项目集成Activiti/Flowable。以下是Maven依赖配置示例dependencies dependency groupIdorg.activiti/groupId artifactIdactiviti-spring-boot-starter/artifactId version7.1.0.M6/version /dependency dependency groupIdcom.h2database/groupId artifactIdh2/artifactId scoperuntime/scope /dependency /dependencies为方便观察网关行为建议在application.properties中开启调试日志logging.level.org.activitiDEBUG创建基础测试类模板后续所有网关测试都将继承此类SpringBootTest public abstract class GatewayTestBase { Autowired private RuntimeService runtimeService; Autowired private TaskService taskService; Autowired private RepositoryService repositoryService; protected ProcessInstance startProcess(String processDefinitionKey, MapString, Object variables) { return runtimeService.startProcessInstanceByKey(processDefinitionKey, variables); } protected void deployProcess(String bpmnFile) { repositoryService.createDeployment() .addClasspathResource(bpmnFile) .deploy(); } }2. 排他网关(Exclusive Gateway)实战解析排他网关是最常用的决策节点其特点是仅选择一条符合条件的路径。我们构建一个订单审核流程来演示其特性process idexclusiveGatewayDemo startEvent idstart/ sequenceFlow idflow1 sourceRefstart targetRefexclusiveGw/ exclusiveGateway idexclusiveGw nameApproval Gateway/ sequenceFlow idflow2 sourceRefexclusiveGw targetRefapproveTask conditionExpression xsi:typetFormalExpression ${order.amount 1000} /conditionExpression /sequenceFlow sequenceFlow idflow3 sourceRefexclusiveGw targetRefmanagerApproveTask conditionExpression xsi:typetFormalExpression ${order.amount 1000 order.amount 5000} /conditionExpression /sequenceFlow sequenceFlow idflow4 sourceRefexclusiveGw targetRefdirectorApproveTask conditionExpression xsi:typetFormalExpression ${order.amount 5000} /conditionExpression /sequenceFlow !-- 各审批任务定义省略 -- /process关键测试案例展示不同金额订单的路由逻辑public class ExclusiveGatewayTest extends GatewayTestBase { Test public void testLowAmountApproval() { MapString, Object vars new HashMap(); vars.put(order, new Order(800)); // 测试金额800元 ProcessInstance pi startProcess(exclusiveGatewayDemo, vars); Task task taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult(); assertEquals(Approve Task, task.getName()); // 验证进入普通审批 } Test public void testHighAmountApproval() { MapString, Object vars new HashMap(); vars.put(order, new Order(6000)); // 测试金额6000元 ProcessInstance pi startProcess(exclusiveGatewayDemo, vars); Task task taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult(); assertEquals(Director Approve Task, task.getName()); // 验证进入总监审批 } }观察引擎日志可以发现关键行为DEBUG o.a.e.i.bpmn.behavior.ExclusiveGatewayActivityBehavior - Leaving exclusive gateway exclusiveGw with sequence flow flow4数据库表ACT_RU_EXECUTION的变化显示无论选择哪条路径都只会有一条执行记录继续流动。提示排他网关的条件表达式应互斥否则引擎会选择XML中第一个符合条件的路径3. 并行网关(Parallel Gateway)并发机制揭秘并行网关用于创建同步的并发路径典型应用场景如订单处理中的支付与发货并行process idparallelGatewayDemo startEvent idstart/ sequenceFlow idflow1 sourceRefstart targetReffork/ parallelGateway idfork/ sequenceFlow idflow2 sourceReffork targetRefpaymentTask/ sequenceFlow idflow3 sourceReffork targetRefshippingTask/ userTask idpaymentTask nameReceive Payment/ userTask idshippingTask nameShip Order/ sequenceFlow idflow4 sourceRefpaymentTask targetRefjoin/ sequenceFlow idflow5 sourceRefshippingTask targetRefjoin/ parallelGateway idjoin/ sequenceFlow idflow6 sourceRefjoin targetRefarchiveTask/ userTask idarchiveTask nameArchive Order/ /process测试代码验证并行执行特性public class ParallelGatewayTest extends GatewayTestBase { Test public void testForkJoinBehavior() { ProcessInstance pi startProcess(parallelGatewayDemo, new HashMap()); // 验证同时创建两个任务 ListTask tasks taskService.createTaskQuery() .processInstanceId(pi.getId()) .orderByTaskName() .asc() .list(); assertEquals(2, tasks.size()); assertEquals(Receive Payment, tasks.get(0).getName()); assertEquals(Ship Order, tasks.get(1).getName()); // 模拟完成支付任务 taskService.complete(tasks.get(0).getId()); // 此时归档任务仍未创建 assertNull(taskService.createTaskQuery() .processInstanceId(pi.getId()) .taskName(Archive Order) .singleResult()); // 完成发货任务后归档任务出现 taskService.complete(tasks.get(1).getId()); assertNotNull(taskService.createTaskQuery() .processInstanceId(pi.getId()) .taskName(Archive Order) .singleResult()); } }数据库观察发现当流程到达fork网关时ACT_RU_EXECUTION表会新增两条记录IDPROC_INST_ID_ACT_ID_IS_ACTIVE_11001fork021001paymentTask131001shippingTask1日志中的关键条目DEBUG o.a.e.i.bpmn.behavior.ParallelGatewayActivityBehavior - Forking execution for parallel gateway fork into 2 branches4. 包容网关(Inclusive Gateway)动态路由剖析包容网关结合了排他与并行网关的特性允许动态决定并行路径数量。典型应用如多条件审批流程process idinclusiveGatewayDemo startEvent idstart/ sequenceFlow idflow1 sourceRefstart targetRefinclusiveGw/ inclusiveGateway idinclusiveGw nameCheck Requirements/ sequenceFlow idflow2 sourceRefinclusiveGw targetReflegalReview conditionExpression xsi:typetFormalExpression ${contract.needLegalReview} /conditionExpression /sequenceFlow sequenceFlow idflow3 sourceRefinclusiveGw targetReffinanceReview conditionExpression xsi:typetFormalExpression ${contract.value 10000} /conditionExpression /sequenceFlow sequenceFlow idflow4 sourceRefinclusiveGw targetReftechReview conditionExpression xsi:typetFormalExpression ${contract.hasTechnicalClause} /conditionExpression /sequenceFlow !-- 各审核任务定义省略 -- inclusiveGateway idjoinGw/ sequenceFlow idflow5 sourceReflegalReview targetRefjoinGw/ sequenceFlow idflow6 sourceReffinanceReview targetRefjoinGw/ sequenceFlow idflow7 sourceReftechReview targetRefjoinGw/ sequenceFlow idflow8 sourceRefjoinGw targetReffinalizeTask/ /process测试案例展示不同场景下的路由组合public class InclusiveGatewayTest extends GatewayTestBase { Test public void testSinglePath() { Contract contract new Contract(); contract.setNeedLegalReview(true); MapString, Object vars new HashMap(); vars.put(contract, contract); ProcessInstance pi startProcess(inclusiveGatewayDemo, vars); ListTask tasks taskService.createTaskQuery() .processInstanceId(pi.getId()) .list(); assertEquals(1, tasks.size()); assertEquals(Legal Review, tasks.get(0).getName()); } Test public void testMultiplePaths() { Contract contract new Contract(); contract.setValue(15000); contract.setHasTechnicalClause(true); MapString, Object vars new HashMap(); vars.put(contract, contract); ProcessInstance pi startProcess(inclusiveGatewayDemo, vars); ListTask tasks taskService.createTaskQuery() .processInstanceId(pi.getId()) .orderByTaskName() .asc() .list(); assertEquals(2, tasks.size()); assertEquals(Finance Review, tasks.get(0).getName()); assertEquals(Technical Review, tasks.get(1).getName()); } }日志中可以看到条件计算过程DEBUG o.a.e.i.bpmn.behavior.InclusiveGatewayActivityBehavior - Evaluating condition on sequence flow flow3: ${contract.value 10000} - true5. 基于事件的网关(Event-based Gateway)异步处理机制基于事件的网关适用于需要等待外部事件触发的场景如订单取消或超时处理process ideventGatewayDemo startEvent idstart/ sequenceFlow idflow1 sourceRefstart targetRefeventGw/ eventBasedGateway ideventGw/ sequenceFlow idflow2 sourceRefeventGw targetRefcancelEvent/ sequenceFlow idflow3 sourceRefeventGw targetReftimeoutEvent/ intermediateCatchEvent idcancelEvent messageEventDefinition messageReforderCancelMsg/ /intermediateCatchEvent intermediateCatchEvent idtimeoutEvent timerEventDefinition timeDurationPT2H/timeDuration /timerEventDefinition /intermediateCatchEvent sequenceFlow idflow4 sourceRefcancelEvent targetRefhandleCancel/ sequenceFlow idflow5 sourceReftimeoutEvent targetRefhandleTimeout/ !-- 各处理任务定义省略 -- /process测试案例展示事件触发机制public class EventGatewayTest extends GatewayTestBase { Test public void testMessageEventTrigger() throws InterruptedException { ProcessInstance pi startProcess(eventGatewayDemo, new HashMap()); // 初始状态无任务 assertNull(taskService.createTaskQuery() .processInstanceId(pi.getId()) .singleResult()); // 模拟发送取消消息 runtimeService.messageEventReceived(orderCancelMsg, pi.getId()); // 验证处理取消的任务被创建 Task task taskService.createTaskQuery() .processInstanceId(pi.getId()) .singleResult(); assertEquals(Handle Cancellation, task.getName()); } Test public void testTimerEventTrigger() { // 需要配置时间偏移测试 } }引擎日志显示事件订阅创建DEBUG o.a.e.i.bpmn.behavior.EventBasedGatewayActivityBehavior - Created event subscription for MessageEventDefinition with message orderCancelMsg数据库表ACT_RU_EVENT_SUBSCR会记录当前等待的事件订阅。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2520017.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!