欢迎光临
我们一直在努力

36-FlowableProcessService方法地图

36-FlowableProcessService:核心封装的方法地图

308行封装了Flowable五大Service的全部常用操作——startProcess/completeTask/退回/驳回/跳转/撤回/待办已办。这篇先给全方法地图,重点拆completeTask的三段式(前置拦截→complete→后置通知)和nextid变量法的退回驳回。

文章目录

  • 36-FlowableProcessService:核心封装的方法地图
    • 一、方法地图
    • 二、completeTask的三段式
    • 三、nextid变量法:不用改BPMN的流转控制
    • 四、jumpToNode:引擎级的任意跳转
    • 五、findFirstUserTask:找起点的两层降级
    • 六、@Autowired(required=false)的两个可选依赖

源码:browise-workflow/src/main/java/com/browise/workflow/service/FlowableProcessService.java(308行)


一、方法地图

类别方法引擎调用
流程 startProcess runtimeService.startProcessInstanceByKey
任务 completeTask taskService.complete(含拦截/通知)
claimTask / unclaimTask 认领/取消
delegateTask / transferTask 委派/转办
退回 backToPrevious nextid变量法(第38篇专述)
终结 finishProcess(通过) nextid=endEvent+approved=true
rejectProcess(驳回) nextid=endEvent+approved=false
cancelProcess / withdrawProcess deleteProcessInstance
跳转 jumpToNode ChangeActivityStateBuilder
查询 getTodoTasks×2 / getDoneTasks assignee/candidate/历史
部署 deploy / getProcessDiagram / getTasksForDiagram 仓库/图(第42篇)

二、completeTask的三段式

public void completeTask(String taskId, Map<String, Object> variables) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
String procInstId = task.getProcessInstanceId();
String taskDefKey = task.getTaskDefinitionKey();

// ───── 第一段:前置拦截器 ─────
if (interceptorChainService != null && ...) {
String procDefKey = getProcessDefKey(procInstId);
interceptorChainService.executeBefore(procDefKey, taskDefKey, taskId, procInstId, variables);
}

// ───── 第二段:引擎推进 ─────
taskService.complete(taskId, variables);

// ───── 第三段:后置拦截器 + 下一任务处理人通知 ─────
if (interceptorChainService != null && ...) {
interceptorChainService.executeAfter(...);
}
if (notifyService != null) {
List<Task> nextTasks = taskService.createTaskQuery()
.processInstanceId(procInstId).active().list(); // complete后的活动任务=新节点
for (Task nt : nextTasks) {
notifyService.sendMessage(nt.getAssignee(), procInstId, "新待办: …");
}
}
}

前置拦截的业务场景——审批通过前校验业务状态(如“参保状态必须是正常”)、锁定数据防并发改。

后置拦截——审批后写业务表(更新参保登记状态)、触发下游(待遇核定)。

第三段通知的时机微妙——complete之后查询active任务,查到的是下一节点的任务(当前任务已完成不在active里)。如果流程走到排他网关,complete返回时路由已定——新任务已产生——查询即得。如果下一节点是并行网关——多个新任务都查到——逐个通知。

try-catch ignored包住通知——通知失败不阻断审批(审批已完成,通知是锦上添花)。第43篇讲Spring事件版本的事务后推送——那是更严谨的方案。


三、nextid变量法:不用改BPMN的流转控制

第37篇专述的机制先给结论——所有特殊流转(退回/通过/驳回)都是“设变量+complete”:

// 退回发起人
runtimeService.setVariable(executionId, "nextid", firstTask.getTaskDefinitionKey());
runtimeService.setVariable(executionId, "user", startUserId);
taskService.complete(taskId);

// 正常结束(通过)
runtimeService.setVariable(executionId, "nextid", "endEvent");
runtimeService.setVariable(executionId, "approved", true);
taskService.complete(taskId);

BPMN网关的条件表达式读nextid——#{nextid == 'usertask1'}决定流转方向。引擎不知道“退回”这个概念——它只看到变量+complete,按网关条件走。退回逻辑全部在应用层,流程图定义保持标准。


四、jumpToNode:引擎级的任意跳转

public void jumpToNode(String taskId, String targetActivityId) {
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
.moveActivityIdTo(task.getTaskDefinitionKey(), targetActivityId)
.changeState();
}

ChangeActivityStateBuilder是Flowable 6.x的官方API——把当前活动移到目标活动,不走BPMN连线、不触发网关判断。和nextid变量法的区别:

nextid变量法jumpToNode
依赖 BPMN网关写好条件 无需改BPMN
路径 按连线走(可经过网关) 直接瞬移
变量副作用 网关沿途可读变量 原样保留
适用 流转可预见(退回/驳回) 管理员强制干预

jumpToNode是管理员兜底工具——流程卡死(变量缺失/网关死路)时强制挪节点。业务代码不该日常用它——瞬移绕过一切校验(网关条件、边界事件、监听器)。


五、findFirstUserTask:找起点的两层降级

private HistoricTaskInstance findFirstUserTask(String processInstanceId) {
// ①历史任务按结束时间升序——第一个完成的就是首节点
List<HistoricTaskInstance> histTasks = historyService...
.finished().orderByHistoricInstanceEndTime().asc().list();
if (!histTasks.isEmpty()) return histTasks.get(0);

// ②无历史(流程刚启动还没人完成过任务)——查活动任务
List<Task> activeTasks = taskService...orderByTaskCreateTime().asc().list();
// 取未完成的历史单条
}

为什么按EndTime不按CreateTime——并行网关下首节点和第二节点可能同时创建——CreateTime排序可能第二节点在前。EndTime保证“最先完成的”——发起人提交必然是第一个完成的动作。

退回到“发起时的第一个用户任务”而不是“上一个任务”——政务语义:退回=打回重报,不是“退一步改改”。


六、@Autowired(required=false)的两个可选依赖

@Autowired(required = false)
private InterceptorChainService interceptorChainService;

@Autowired(required = false)
private WorkflowNotifyService notifyService;

可选注入——workflow模块被裁剪装配时(只要引擎不要拦截/通知),服务照样能跑。completeTask里的null检查对应这个设计。模块内也保持松耦合——拦截器链和通知是增强不是依赖。


✅ 亮点:308行的方法地图+completeTask三段式逐段拆、通知查询active任务拿到的是下一节点任务、nextid变量法与jumpToNode的适用对照、findFirstUserTask按EndTime排序的并行网关细节。适合封装流程引擎的人。扩展方向:第37篇nextid专述、第38篇退回驳回、第41篇拦截器链。

赞(0)
未经允许不得转载:171主机测评 » 36-FlowableProcessService方法地图
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址