一份面向研发与架构的评估框架:把二开能力抽象为交互层、服务层与配置编排层,并用同一把尺子对照 Java 与 .NET 两侧常见开源产品的实现方式与能力边界。
流程引擎二开 = 流程(模板)设计完成之后,在不修改引擎内核发送 / 流转代码的前提下,用脚本、类、配置或 Worker,与引擎在固定生命周期点交互,从而完成业务校验、集成、通知、台账等逻辑的过程。
对比项 | 改引擎源码 | 流程二开(本文范围) |
|---|---|---|
改动位置 | 发送 / 退回 / 调度内核 | 外挂、事件、自定义 Activity、配置执行体 |
升级成本 | 高,难合并 | 相对低,核心可独立升级 |
职责边界 | 引擎与业务缠在一起 | 引擎管流转,二开管业务 |
可交付性 | 难复用、难交接 | 可按流程模板 / 模块绑定交付 |
典型动作:发送前校验、发送后同步第三方、退回拦截、流程结束写台账、自定义活动节点、自定义办理页按钮等。
各产品对「挂业务」的叫法并不统一:Listener、Delegate、Action、StepBody、Custom Activity、外挂、事件配置、ServiceTask…… 评估时不必纠结名词,应看三件事是否成立:
这三件事,正是下文「三层挂接模型」要回答的。
把二开能力按「谁写、写在哪、管什么边界」拆成三层:
层级 | 名称 | 一句话 | 谁写 | 典型载体 | 擅长 | 不适合单独承担 |
|---|---|---|---|---|---|---|
L1 | 交互层 | 前端 / 页面侧写脚本交互 | 前端 / 全栈 | 办理页钩子、表单脚本、设计器 UI 插件 | 发送前校验、按钮定制、提示、字段联动 | 强事务写库、跨系统强一致 |
L2 | 服务层 | 后端 / 进程内写代码 | 后端 | JavaDelegate、Listener、FlowEvent、StepBody、自定义 Activity | 强事务、改接收人 / 跳转、同步 ERP、审计 | 纯 UI 即时反馈 |
L3 | 配置 / 编排层 | 设计器或模型配置 | 实施 / 低代码 | SQL / HTTP / 脚本 / 表达式 / CodeAction | 少写代码也能挂业务 | 复杂分支、深度引擎变量重构 |
运行时可以理解为同一条业务动作的分层叠加(示意):
用户点击「发送」
├─ L1 交互层:页面校验 / 拦截 / 按钮与提示
└─ 请求进入引擎
├─ L2 服务层:进程内代码(可改路由、写库、调系统)
└─ L3 配置层:SQL / HTTP / 脚本 / 表达式(实施可配)关键认识:三层不是互斥三选一,而是允许叠加。常见顺序是 L1 先拦人机边界 → L2 再守系统真相 → L3 承接标准化连接。
选型时如果只看「有没有设计器 / 是否 BPMN」,很容易漏掉真正决定项目成败的问题:
若二开能力弱 | 项目侧常见后果 |
|---|---|
只能改源码挂业务 | 升级噩梦、合并冲突、人员不敢动引擎 |
只有后端代码扩展 | 前端交互与实施配置缺位,交付慢、协作成本高 |
只有配置没有代码出口 | 复杂规则被迫塞进脚本地狱,难测难重构 |
事件时钟不产品化 | 团队靠猜「什么时候会触发」,集成不可控 |
因此:二开不是售后补丁,而是引擎产品能力的一等公民。 尤其在政企审批、ERP 集成、多系统待办同步等场景,L1/L2/L3 是否齐全,往往比「画布好不好看」更能决定能不能按期上线、能不能长期维护。
问题:发送前要不要先提示?字段要不要联动?按钮要不要定制?成功后要不要局部刷新?
价值:反馈即时,减少无效请求;把「人机交互边界」拦在浏览器侧。 边界:页面可拦截,但业务真相以服务端为准——金额、库存、权限最终仍应在 L2/L3 再校验一遍。
常见形态:
问题:要不要改下一节点接收人?要不要同步 ERP?要不要写审计台账?要不要在同一事务里失败回滚?
价值:强类型、可调试、可测试;能访问运行时上下文(当前节点、实例 ID、变量、发送结果等)。 边界:适合系统集成与规则编排;不适合用它替代页面即时交互。
常见形态:
JavaDelegate、ExecutionListener、TaskListener StepBody、Custom Activity、Action Provider、流程事件基类 问题:没有专职开发时,实施能否在设计器里把「一条 SQL / 一个 HTTP / 一段表达式」挂上?
价值:把简单集成从程序员日程里解放出来;缩短交付周期。 边界:擅长标准化连接;复杂分支、深度重构仍应回到 L2。
常见形态:
资料依据为各产品公开文档与社区常见做法。评级是「机制完整度」,不是业务场景总分。 强 = 产品级、文档/样例完整;中 = 能做但需自建较多;弱 = 基本不覆盖或需从零实现。
产品 | 定位倾向 | L1 交互层 | L2 服务层 | L3 配置编排 | 二开主叙事 |
|---|---|---|---|---|---|
Camunda(社区版 / 平台) | BPMN 标准向编排 + 运维 | 中(表单/办理页多自建或另接;Cockpit/Tasklist 可扩展但非审批门户一站式) | 强(JavaDelegate、Execution/Task Listener、外部任务) | 强(脚本、表达式、Listener 配置、Connector 生态) | Listener + Delegate + External Task |
Flowable | BPMN / CMMN 引擎族 | 中(UI 多自建;企业版能力更完整) | 强(Delegate、Listener、解析期注入 Listener) | 强(expression / script / class 挂接) | 与 Camunda 同源思想,Delegate Code 体系 |
Activiti | 经典 BPMN 引擎 | 中偏弱(产品 UI 依赖版本与生态) | 强(JavaDelegate、Listener) | 强偏中(脚本/表达式可用,实施配置体验因发行版而异) | 经典委托代码模型 |
该引擎 | 流程 + 表单一体化 BPM(Java) | 强(办理页前端外挂协议产品化) | 强(流程事件基类 / 后端外挂) | 强(模板事件配置:SQL/HTTP/脚本等) | 前端外挂 + 后端外挂 + 事件配置 |
三者同属 Activiti 谱系或其近亲,二开骨架高度相似:
层级 | 典型落点 |
|---|---|
L2 | JavaDelegate(Service Task)、ExecutionListener(执行开始/结束)、TaskListener(人工任务 create/assignment/complete…) |
L3 | BPMN extensionElements 中配置 class / delegateExpression / expression / script;Script Task;条件表达式 |
L1 | 引擎本身通常不强制提供与审批办理页对齐的「前端外挂协议」;表单与工作台多由业务系统自建,或依赖 Tasklist / 商业套件 / 自研前端 |
特点:
该引擎与下文 .NET 侧的该引擎 同根同源、语言不同:事件名、分层思想、调度顺序一致,差异主要在 Java 包机制与 .NET 程序集机制。 产品概念上常称为:前端外挂(L1)、后端外挂(L2)、模板事件配置(L3)。详见第 6 节。
你更关心… | 相对更贴的路径 |
|---|---|
标准 BPMN + 强代码扩展 + 云原生 Worker | Camunda / Flowable |
轻量嵌入、经典委托模型 | Activiti 谱系引擎 |
审批办理页也能产品级挂脚本,且配置/代码并列 | 该引擎这类一体化 BPM |
产品 | 定位倾向 | L1 交互层 | L2 服务层 | L3 配置编排 | 二开主叙事 |
|---|---|---|---|---|---|
Elsa Workflows | 通用长流程编排 + Studio | 中偏强(Studio 元数据/UIHint;业务办理页多自建) | 强(Custom Activity、Middleware、Module/Feature) | 中(活动组合与表达式强;SQL/实施配置弱于 BPM) | 自定义 Activity 生态 |
Workflow Core | 轻量嵌入式流程库 | 弱(几乎无产品级办理 UI) | 强(StepBody + 中间件) | 中(JSON/YAML 引用 Step 类型) | 步骤即扩展单元 |
WorkflowEngine.NET | 可嵌入引擎(生产多需商业许可) | 强(设计器模板 / 表单可定制) | 强(Action Provider、Plugin、Custom Activity) | 强(方案内 CodeActions 等) | Action + Plugin |
Slickflow | BPMN 风格 .NET 引擎 | 中(设计师可嵌;业务页多自建) | 强(ExternalService、引擎 API) | 强(本地类 / WebApi / SQL / 过程) | 节点 Action 多执行体 |
该引擎 | 流程 + 表单 + 组织一体化 BPM | 强(Vue 前端外挂) | 强(FlowEventBase 后端外挂) | 强(设计器事件 + SQL/WebApi/过程等) | 前端外挂 + 后端外挂 + 事件配置 |
StepBody 即业务单元,嵌入成本低;几乎没有产品级设计器/表单/待办门户——二开 ≈ 写代码 + 自建 UI。见下一节——用同源实现对 L1/L2/L3 做「可核对」说明,而不是把某一品牌写成唯一正确答案。
你更关心… | 相对更贴的路径 |
|---|---|
自定义流程积木、云原生编排 | Elsa、Workflow Core |
设计器内 Action / 商业嵌入 | WorkflowEngine.NET |
BPMN 节点挂服务 / SQL / WebApi | Slickflow |
审批生命周期 + 办理页外挂 + 配置事件 | 该引擎 / 同类一体化 BPM |
二者事件模型同源:同一套事件语义(如发送前 / 发送成功 / 流程结束后),三种写法并列。 本节只做机制对照与源码索引,便于读者用公开实现核对「三层模型」是否可落地;不作为唯一选型结论。
三层模型 | 产品概念(该引擎) | 含义 |
|---|---|---|
L1 交互层 | 前端外挂 | 浏览器侧挂流程脚本:校验、按钮、提示、联动 |
L2 服务层 | 后端外挂 | 服务端强类型事件类:事务、改人、集成、审计 |
L3 配置层 | 模板事件配置 | 设计器挂 SQL / HTTP / 脚本 / 业务单元等 |
服务端调度思想(示意):全局拦截 → 流程级后端外挂 → 配置事件 → 消息推送(与业务事件共用时钟、职责分离)。
用户点击发送
├─ ① L1:前端外挂(可拦截)
└─ ② HTTP → 引擎发送编排
└─ 统一事件调度
├─ 全局后端拦截
├─ L2:流程事件基类(后端外挂)
├─ L3:事件配置 / 数据源执行体(模板事件配置)
└─ 消息推送(同事件标记,独立配置)
└─ ③ L1:发送成功后的前端副作用约定:外挂类名以 FlowExt_ 开头,并绑定流程号;与后端认同一套事件名(如 SendWhen / SendSuccess)。
protected constructor(classID: string, flowNo: string) {
if (classID.includes('FlowExt_') == false) {
message.warning('外挂类名[' + classID + ']不符合规范,必须是以 FlowExt_ 开头.');
return;
}
super(classID);
this.FlowNo = flowNo;
}适合 | 说明 |
|---|---|
发送前弹窗校验、字段联动、按钮定制 | 反馈在页面完成 |
发送成功后的提示 / 局部刷新 | 不替代服务端写库 |
基类约定要点(两端一致):
FlowMark / getFlowMark) .NET Demo(该引擎):
public class 后端外挂示例 : FlowEventBase
{
public override string FlowMark
{
get { return ",065,"; }
}
public override string SendWhen
{
if (1 == 3)
return "err@不符合流程发起条件,阻止流程发送。";
if (1 == 1)
return "后端外挂 /App/Demo/后端外挂示例 SendWhen 已经执行成功,节点ID:" + this.HisNode.NodeID + ",WorkID:" + this.WorkID;Java Demo(该引擎):bp.App.Demo.WaiGua.WaiGuaFlow 继承 bp.wf.FlowEventBase,通过 getFlowMark 绑定流程,重写 SendWhen 等——与 .NET 侧同一设计。
适合 | 说明 |
|---|---|
同步 ERP、改接收人、写台账 | 强一致、可调试 |
全公司统一审计 | 走全局拦截,而不是每个流程复制粘贴 |
在设计器为节点 / 流程 / 表单挂执行体,写入事件配置(如 Sys_事件配置),执行体可为 SQL、WebApi、存储过程、事件类、业务单元等。
挂接点示例 | 配置做法(L3) | 代码做法(L2) |
|---|---|---|
发送前 | SQL 校验金额是否超限 | 后端外挂复杂规则 + 改接收人 |
发送成功 | WebApi 同步外部系统 | 后端外挂写第三方待办 |
流程结束 | 过程归档 | 后端关外部待办 + 前端提示 |
该引擎证明了一件事:
三层挂接不必只存在于论文里——可以把 L1/L2/L3 做成同一事件时钟上的并列入口,让前端、后端、实施各走各的路,又在同一生命周期点汇合。
同时应看到边界:这类产品的扩展叙事偏「审批事件挂业务」,与 Elsa 那种「自定义画布 Activity 生态」不是同一赛道;选型时应按自己的主场景对齐,而不是按品牌热度对齐。
评估任意引擎时,可用下面清单做「可核对」提问(建议对方给文档或样例,而不是口头承诺):
场景 | 更优先的层 | 原因 |
|---|---|---|
发送前弹窗、禁用按钮、字段联动 | L1 | 反馈即时 |
同步 ERP、改接收人、写业务台账 | L2 | 强一致、可调试 |
一条 SQL / 一个 HTTP 就能完成 | L3 | 实施可配,最快 |
全公司统一审计 / 组织策略 | L2 全局 | 一次拦截,全流程生效 |
前端团队强、后端紧 | L1 + L3 | 交互与简单集成分流 |
后端团队强、要长期演进 | L2 为主 | 可测试、可重构、可版本管理 |
标准 BPMN 微服务编排 | L2 Activity/Delegate + 可选 External Task | 积木与 Worker 更贴 |
政企审批 + 表单一体化交付 | L1+L2+L3 产品化是否齐全 | 三层缺一都会转嫁成本 |
流程引擎的竞争力,不只在「把图画出来」,更在:
业务能不能稳稳挂上去——挂在交互层、服务层、还是配置层——并且始终不污染内核。
三层挂接模型给出的是一把跨产品、跨语言的尺子:
Java 阵营里,Camunda / Flowable / Activiti 把 L2/L3 做到了行业标杆,L1 多依赖外围表单与自建工作台;该引擎则把三层做成办理页协议与设计器配置的并列能力。 .NET 阵营里,Elsa / Workflow Core 偏开发者编排,WorkflowEngine.NET / Slickflow 偏设计器与节点执行体,该引擎与该引擎同源,用前端外挂 / 后端外挂 / 事件配置覆盖三层。
没有绝对的第一名,只有与场景对齐的挂接方式。 选型时,把对方的名词翻译回 L1/L2/L3,再用第 7 节清单逐项核对——比比较口号更接近工程真相。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。