别再只会画流程图了!Flowable设计器里任务监听器和多实例的高级玩法详解
2026/6/6 2:19:07 网站建设 项目流程

Flowable高阶实战:任务监听器与多实例的深度应用

当你在Flowable流程设计器中熟练地拖拽节点、连接线条时,是否曾思考过如何让静态的流程图具备动态智能?本文将带你突破基础流程设计的局限,探索任务监听器和多实例这两项高阶特性的实战应用场景。

1. 任务监听器的动态魔法

任务监听器是Flowable中最强大的扩展点之一,它允许我们在任务生命周期的关键节点注入自定义逻辑。不同于固定分配审批人的简单方式,监听器能实现真正的动态流程控制。

1.1 四大事件类型解析

Flowable提供了四种核心监听事件,每种都对应特定的业务场景:

  • create:任务创建时触发

    public class DynamicAssigneeListener implements TaskListener { @Override public void notify(DelegateTask task) { String department = (String) task.getVariable("dept"); String assignee = userService.findDeptManager(department); task.setAssignee(assignee); } }

    提示:此监听器适合需要根据运行时数据动态指定处理人的场景,如跨部门协作流程

  • assignment:任务被签收时执行

    public class AssignmentAlertListener implements TaskListener { @Override public void notify(DelegateTask task) { String message = "任务"+task.getName()+"已被"+task.getAssignee()+"签收"; notificationService.send(message); } }
  • complete:任务完成时触发业务逻辑

    public class PostTaskActionListener implements TaskListener { @Override public void notify(DelegateTask task) { if("财务审批".equals(task.getName())){ accountingService.createVoucher( task.getVariable("amount"), task.getVariable("voucherType") ); } } }
  • delete:任务删除前执行清理操作

1.2 实战配置技巧

在设计器中配置监听器时,有几个关键细节需要注意:

  1. 类路径配置

    • 确保监听器类位于项目的classpath中
    • 使用全限定类名(包括包名)
  2. 变量访问

    // 获取流程变量 Object value = task.getVariable("varName"); // 设置流程变量 task.setVariable("result", approvalResult);
  3. 异常处理

    • 监听器中抛出异常会导致流程中断
    • 建议在监听器内部捕获处理业务异常
  4. 性能考量

    • 避免在监听器中执行耗时操作
    • 对于需要长时间处理的任务,建议使用ServiceTask

2. 多实例模式的进阶应用

多实例特性允许单个节点在运行时生成多个任务实例,这为会签、循环审批等复杂场景提供了优雅的解决方案。

2.1 串行与并行模式对比

特性串行(Sequential)并行(Parallel)
执行方式顺序执行同时执行
适用场景层级审批部门会签
资源消耗较低较高
完成条件所有实例完成所有实例完成
变量隔离支持支持

2.2 动态基数配置

多实例的基数(循环次数)可以通过表达式动态确定:

<userTask id="multiInstanceTask" name="部门会签"> <multiInstanceLoopCharacteristics isSequential="false"> <loopCardinality>${deptCount}</loopCardinality> </multiInstanceLoopCharacteristics> </userTask>

更复杂的场景可以使用集合变量:

<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="${approvers}" flowable:elementVariable="approver"> </multiInstanceLoopCharacteristics>

对应的Java代码设置变量:

List<String> approvers = Arrays.asList("user1","user2","user3"); runtimeService.setVariable(processInstanceId, "approvers", approvers);

2.3 完成条件定制

默认情况下,所有实例完成后多实例节点才会继续流转。我们可以通过completionCondition定制完成规则:

<multiInstanceLoopCharacteristics> <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6}</completionCondition> </multiInstanceLoopCharacteristics>

这个配置表示当60%的实例完成时即可继续流程,适合"多数同意"的业务场景。

3. 组合应用实战案例

让我们通过一个采购审批流程,展示如何组合使用任务监听器和多实例。

3.1 场景需求

  • 采购金额≤1万:部门经理审批
  • 1万<金额≤5万:部门会签(3个相关科室)
  • 金额>5万:需要财务总监和总经理串行审批

3.2 流程实现

节点设计

  1. 开始节点:提交采购申请
  2. 网关:根据金额路由
  3. 多实例会签任务(并行)
  4. 串行审批任务
  5. 结束节点

关键配置

会签节点的监听器配置:

public class DeptAuditorListener implements TaskListener { @Override public void notify(DelegateTask task) { String deptId = (String) task.getVariable("applyDept"); List<String> auditors = deptService.getAuditors(deptId); task.setVariable("auditors", auditors); } }

XML配置片段:

<userTask id="deptAudit" name="部门会签"> <extensionElements> <flowable:taskListener event="create" class="com.example.DeptAuditorListener"/> </extensionElements> <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="${auditors}" flowable:elementVariable="auditor"> <completionCondition>${nrOfCompletedInstances >= 2}</completionCondition> </multiInstanceLoopCharacteristics> </userTask>

4. 性能优化与调试技巧

当流程复杂度增加时,需要特别注意性能问题和调试方法。

4.1 性能优化建议

  1. 监听器优化

    • 避免在监听器中执行数据库长事务
    • 考虑使用异步监听器
  2. 多实例优化

    <multiInstanceLoopCharacteristics isSequential="false" flowable:async="true" flowable:exclusive="false"> </multiInstanceLoopCharacteristics>
  3. 批量操作

    // 批量完成任务 List<Task> tasks = taskService.createTaskQuery() .processInstanceId(processInstanceId) .list(); for(Task task : tasks){ taskService.complete(task.getId()); }

4.2 调试技巧

  1. 历史记录查询

    HistoricActivityInstanceQuery query = historyService .createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId);
  2. 变量跟踪

    Map<String, Object> variables = runtimeService.getVariables(executionId);
  3. 事件日志

    SELECT * FROM ACT_RU_EVENT_SUBSCR WHERE PROC_INST_ID_ = '流程实例ID';
  4. 可视化跟踪

    ProcessDiagramGenerator diagramGenerator = processEngine.getProcessEngineConfiguration() .getProcessDiagramGenerator(); InputStream diagram = diagramGenerator.generateDiagram( bpmnModel, "png", runtimeService.getActiveActivityIds(processInstanceId) );

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询