首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >工作流引擎二开能力评估:三层挂接模型的对照视角

工作流引擎二开能力评估:三层挂接模型的对照视角

原创
作者头像
驰骋工作流程
发布于 2026-10-13 10:16:25
发布于 2026-10-13 10:16:25
110
举报

一份面向研发与架构的评估框架:把二开能力抽象为交互层、服务层与配置编排层,并用同一把尺子对照 Java 与 .NET 两侧常见开源产品的实现方式与能力边界。

1. 先把「二开」说清楚

1.1 什么叫流程引擎的二开

流程引擎二开 = 流程(模板)设计完成之后,在不修改引擎内核发送 / 流转代码的前提下,用脚本、类、配置或 Worker,与引擎在固定生命周期点交互,从而完成业务校验、集成、通知、台账等逻辑的过程。

对比项

改引擎源码

流程二开(本文范围)

改动位置

发送 / 退回 / 调度内核

外挂、事件、自定义 Activity、配置执行体

升级成本

高,难合并

相对低,核心可独立升级

职责边界

引擎与业务缠在一起

引擎管流转,二开管业务

可交付性

难复用、难交接

可按流程模板 / 模块绑定交付

典型动作:发送前校验、发送后同步第三方、退回拦截、流程结束写台账、自定义活动节点、自定义办理页按钮等。

1.2 为什么产品名词各异,却是同一件事

各产品对「挂业务」的叫法并不统一:Listener、Delegate、Action、StepBody、Custom Activity、外挂、事件配置、ServiceTask…… 评估时不必纠结名词,应看三件事是否成立:

  1. 有没有稳定的生命周期时钟(发送前 / 发送后 / 完成 / 退回 / 结束……)
  2. 业务代码是否落在内核之外(可独立升级、可按模板绑定)
  3. 前端、后端、配置是否都能接到同一套语义(或至少有清晰分层)

这三件事,正是下文「三层挂接模型」要回答的。


2. 三层挂接模型:L1 / L2 / L3

把二开能力按「谁写、写在哪、管什么边界」拆成三层:

层级

名称

一句话

谁写

典型载体

擅长

不适合单独承担

L1

交互层

前端 / 页面侧写脚本交互

前端 / 全栈

办理页钩子、表单脚本、设计器 UI 插件

发送前校验、按钮定制、提示、字段联动

强事务写库、跨系统强一致

L2

服务层

后端 / 进程内写代码

后端

JavaDelegate、Listener、FlowEvent、StepBody、自定义 Activity

强事务、改接收人 / 跳转、同步 ERP、审计

纯 UI 即时反馈

L3

配置 / 编排层

设计器或模型配置

实施 / 低代码

SQL / HTTP / 脚本 / 表达式 / CodeAction

少写代码也能挂业务

复杂分支、深度引擎变量重构

运行时可以理解为同一条业务动作的分层叠加(示意):

代码语言:javascript
复制
用户点击「发送」
  ├─ L1 交互层:页面校验 / 拦截 / 按钮与提示
  └─ 请求进入引擎
        ├─ L2 服务层:进程内代码(可改路由、写库、调系统)
        └─ L3 配置层:SQL / HTTP / 脚本 / 表达式(实施可配)

关键认识:三层不是互斥三选一,而是允许叠加。常见顺序是 L1 先拦人机边界 → L2 再守系统真相 → L3 承接标准化连接。

2.1 这一能力的作用

  1. 把「流转」和「业务」拆开:引擎回答怎么走,二开回答走到某点时业务做什么。
  2. 把交付从「改核」变成「挂点」:项目差异落在外挂与配置,而不是 fork 一份引擎。
  3. 让不同角色都能参与:前端、后端、实施不必挤在同一条技术路径上。
  4. 让升级成为可能:内核独立演进,业务扩展可保留、可迁移、可按模板复用。

2.2 为什么它是重要评估指标

选型时如果只看「有没有设计器 / 是否 BPMN」,很容易漏掉真正决定项目成败的问题:

若二开能力弱

项目侧常见后果

只能改源码挂业务

升级噩梦、合并冲突、人员不敢动引擎

只有后端代码扩展

前端交互与实施配置缺位,交付慢、协作成本高

只有配置没有代码出口

复杂规则被迫塞进脚本地狱,难测难重构

事件时钟不产品化

团队靠猜「什么时候会触发」,集成不可控

因此:二开不是售后补丁,而是引擎产品能力的一等公民。 尤其在政企审批、ERP 集成、多系统待办同步等场景,L1/L2/L3 是否齐全,往往比「画布好不好看」更能决定能不能按期上线、能不能长期维护。


3. 三层分别解决什么问题

3.1 L1 交互层:人还在页面上时

问题:发送前要不要先提示?字段要不要联动?按钮要不要定制?成功后要不要局部刷新?

价值:反馈即时,减少无效请求;把「人机交互边界」拦在浏览器侧。 边界:页面可拦截,但业务真相以服务端为准——金额、库存、权限最终仍应在 L2/L3 再校验一遍。

常见形态:

  • 办理页 / 表单脚本(发送前、打开后、字段变更)
  • 前端外挂类 / Override 钩子
  • 设计器 UI 扩展(工具栏、表单控件、画布元素)

3.2 L2 服务层:进入引擎事务边界之后

问题:要不要改下一节点接收人?要不要同步 ERP?要不要写审计台账?要不要在同一事务里失败回滚?

价值:强类型、可调试、可测试;能访问运行时上下文(当前节点、实例 ID、变量、发送结果等)。 边界:适合系统集成与规则编排;不适合用它替代页面即时交互。

常见形态:

  • Java:JavaDelegate、ExecutionListener、TaskListener
  • .NET:StepBody、Custom Activity、Action Provider、流程事件基类
  • 全局拦截 / 中间件(平台级策略)+ 流程级绑定(模板级策略)

3.3 L3 配置 / 编排层:少写代码也能挂

问题:没有专职开发时,实施能否在设计器里把「一条 SQL / 一个 HTTP / 一段表达式」挂上?

价值:把简单集成从程序员日程里解放出来;缩短交付周期。 边界:擅长标准化连接;复杂分支、深度重构仍应回到 L2。

常见形态:

  • BPMN 扩展:Listener / ServiceTask 上挂 class / expression / script
  • 设计器事件:SQL、WebApi、存储过程、业务单元
  • 方案内 CodeAction、表达式语言(JUEL / FEEL / 自有 DSL)

4. 流行引擎怎么实现:Java 阵营

资料依据为各产品公开文档与社区常见做法。评级是「机制完整度」,不是业务场景总分。 强 = 产品级、文档/样例完整;中 = 能做但需自建较多;弱 = 基本不覆盖或需从零实现。

4.1 总对照(Java)

产品

定位倾向

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/脚本等)

前端外挂 + 后端外挂 + 事件配置

Camunda / Flowable / Activiti:同一套「BPMN 扩展点」思维

三者同属 Activiti 谱系或其近亲,二开骨架高度相似:

层级

典型落点

L2

JavaDelegate(Service Task)、ExecutionListener(执行开始/结束)、TaskListener(人工任务 create/assignment/complete…)

L3

BPMN extensionElements 中配置 class / delegateExpression / expression / script;Script Task;条件表达式

L1

引擎本身通常不强制提供与审批办理页对齐的「前端外挂协议」;表单与工作台多由业务系统自建,或依赖 Tasklist / 商业套件 / 自研前端

特点:

  • L2/L3 极强:开发者友好,生态成熟,适合微服务与标准 BPMN。
  • L1 往往外置:若你的项目强依赖「办理页发送前校验、按钮定制、字段联动」的产品级协议,需要额外评估表单/门户方案。
  • External Task(Camunda 等) 把重活外移到 Worker,适合解耦与多语言工人进程——这是 L2 的「进程外变体」,仍属服务侧挂接。
该引擎:把三层做成并列入口

该引擎与下文 .NET 侧的该引擎 同根同源、语言不同:事件名、分层思想、调度顺序一致,差异主要在 Java 包机制与 .NET 程序集机制。 产品概念上常称为:前端外挂(L1)、后端外挂(L2)、模板事件配置(L3)。详见第 6 节。

4.2 Java 阵营怎么读表

你更关心…

相对更贴的路径

标准 BPMN + 强代码扩展 + 云原生 Worker

Camunda / Flowable

轻量嵌入、经典委托模型

Activiti 谱系引擎

审批办理页也能产品级挂脚本,且配置/代码并列

该引擎这类一体化 BPM


5. 流行引擎怎么实现:.NET 阵营

5.1 总对照(.NET)

产品

定位倾向

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/过程等)

前端外挂 + 后端外挂 + 事件配置

Elsa / Workflow Core:开发者编排优先
  • Elsa:二开主路径是「自定义积木」(Activity)+ 中间件 + 可打包扩展;对人机审批语义(会签、组织待办)通常要自建。
  • Workflow Core:StepBody 即业务单元,嵌入成本低;几乎没有产品级设计器/表单/待办门户——二开 ≈ 写代码 + 自建 UI。
WorkflowEngine.NET / Slickflow:设计器与节点执行体
  • WorkflowEngine.NET:Action/Condition、CodeActions、Plugin、Custom Activity 文档完整;许可需单独评估。
  • Slickflow:节点上挂本地服务 / WebApi / SQL / 过程,BPMN 语义清晰;前端「办理页外挂协议」完整度因产品线而异。
该引擎:与该引擎同一套三层协议

见下一节——用同源实现对 L1/L2/L3 做「可核对」说明,而不是把某一品牌写成唯一正确答案。

5.2 .NET 阵营怎么读表

你更关心…

相对更贴的路径

自定义流程积木、云原生编排

Elsa、Workflow Core

设计器内 Action / 商业嵌入

WorkflowEngine.NET

BPMN 节点挂服务 / SQL / WebApi

Slickflow

审批生命周期 + 办理页外挂 + 配置事件

该引擎 / 同类一体化 BPM


6. 同源实证:该引擎(Java)与该引擎(.NET)如何落在三层上

二者事件模型同源:同一套事件语义(如发送前 / 发送成功 / 流程结束后),三种写法并列。 本节只做机制对照与源码索引,便于读者用公开实现核对「三层模型」是否可落地;不作为唯一选型结论。

6.1 概念映射

三层模型

产品概念(该引擎)

含义

L1 交互层

前端外挂

浏览器侧挂流程脚本:校验、按钮、提示、联动

L2 服务层

后端外挂

服务端强类型事件类:事务、改人、集成、审计

L3 配置层

模板事件配置

设计器挂 SQL / HTTP / 脚本 / 业务单元等

服务端调度思想(示意):全局拦截 → 流程级后端外挂 → 配置事件 → 消息推送(与业务事件共用时钟、职责分离)。

代码语言:javascript
复制
用户点击发送
  ├─ ① L1:前端外挂(可拦截)
  └─ ② HTTP → 引擎发送编排
        └─ 统一事件调度
              ├─ 全局后端拦截
              ├─ L2:流程事件基类(后端外挂)
              ├─ L3:事件配置 / 数据源执行体(模板事件配置)
              └─ 消息推送(同事件标记,独立配置)
        └─ ③ L1:发送成功后的前端副作用

6.2 L1:前端外挂(以该引擎 Vue3 为例)

约定:外挂类名以 FlowExt_ 开头,并绑定流程号;与后端认同一套事件名(如 SendWhen / SendSuccess)。

代码语言:javascript
复制
  protected constructor(classID: string, flowNo: string) {
    if (classID.includes('FlowExt_') == false) {
      message.warning('外挂类名[' + classID + ']不符合规范,必须是以 FlowExt_ 开头.');
      return;
    }
    super(classID);
    this.FlowNo = flowNo;
  }

适合

说明

发送前弹窗校验、字段联动、按钮定制

反馈在页面完成

发送成功后的提示 / 局部刷新

不替代服务端写库

6.3 L2:后端外挂(.NET 与 Java 对照)

基类约定要点(两端一致):

  1. 子类重写事件方法与引擎交互
  2. 一个子类与一个(组)流程模板绑定(FlowMark / getFlowMark)
  3. 基类暴露运行时变量,降低重复查询
  4. 类进入约定程序集 / 包后由工厂发现

.NET Demo(该引擎):

代码语言:javascript
复制
    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、改接收人、写台账

强一致、可调试

全公司统一审计

走全局拦截,而不是每个流程复制粘贴

6.4 L3:模板事件配置

在设计器为节点 / 流程 / 表单挂执行体,写入事件配置(如 Sys_事件配置),执行体可为 SQL、WebApi、存储过程、事件类、业务单元等。

挂接点示例

配置做法(L3)

代码做法(L2)

发送前

SQL 校验金额是否超限

后端外挂复杂规则 + 改接收人

发送成功

WebApi 同步外部系统

后端外挂写第三方待办

流程结束

过程归档

后端关外部待办 + 前端提示

6.5 同源实现的启发(公平表述)

该引擎证明了一件事:

三层挂接不必只存在于论文里——可以把 L1/L2/L3 做成同一事件时钟上的并列入口,让前端、后端、实施各走各的路,又在同一生命周期点汇合。

同时应看到边界:这类产品的扩展叙事偏「审批事件挂业务」,与 Elsa 那种「自定义画布 Activity 生态」不是同一赛道;选型时应按自己的主场景对齐,而不是按品牌热度对齐。


7. 用三层模型做选型:一张检查清单

评估任意引擎时,可用下面清单做「可核对」提问(建议对方给文档或样例,而不是口头承诺):

L1 交互层

  • 办理页是否有稳定的发送前 / 发送后钩子?
  • 能否定制按钮、提示、字段联动,且不改引擎前端内核?
  • 前端事件名是否与后端生命周期对齐(或有明确映射表)?

L2 服务层

  • 能否在发送前拦截并回滚?
  • 能否读取并改写路由 / 接收人 / 流程变量?
  • 扩展是否按流程模板绑定,并可独立部署(程序集 / 包 / NuGet / jar)?
  • 是否区分「全局策略」与「单流程策略」?

L3 配置编排层

  • 设计器能否挂 SQL / HTTP / 脚本 / 表达式,而无需每次发版?
  • 配置执行体失败时,错误是否可观测、可阻断?
  • 简单集成走配置、复杂逻辑走代码,路径是否清晰?

跨层原则

  • 三层是否允许叠加,顺序是否文档化?
  • 消息推送与业务脚本是否解耦(同事件点、分职责)?
  • 升级引擎时,业务扩展目录是否默认不被覆盖?

8. 场景 × 层级:怎么选,而不是怎么站队

场景

更优先的层

原因

发送前弹窗、禁用按钮、字段联动

L1

反馈即时

同步 ERP、改接收人、写业务台账

L2

强一致、可调试

一条 SQL / 一个 HTTP 就能完成

L3

实施可配,最快

全公司统一审计 / 组织策略

L2 全局

一次拦截,全流程生效

前端团队强、后端紧

L1 + L3

交互与简单集成分流

后端团队强、要长期演进

L2 为主

可测试、可重构、可版本管理

标准 BPMN 微服务编排

L2 Activity/Delegate + 可选 External Task

积木与 Worker 更贴

政企审批 + 表单一体化交付

L1+L2+L3 产品化是否齐全

三层缺一都会转嫁成本


9. 结语

流程引擎的竞争力,不只在「把图画出来」,更在:

业务能不能稳稳挂上去——挂在交互层、服务层、还是配置层——并且始终不污染内核。

三层挂接模型给出的是一把跨产品、跨语言的尺子:

  • L1 守人机边界
  • L2 守系统真相
  • L3 释放实施生产力

Java 阵营里,Camunda / Flowable / Activiti 把 L2/L3 做到了行业标杆,L1 多依赖外围表单与自建工作台;该引擎则把三层做成办理页协议与设计器配置的并列能力。 .NET 阵营里,Elsa / Workflow Core 偏开发者编排,WorkflowEngine.NET / Slickflow 偏设计器与节点执行体,该引擎与该引擎同源,用前端外挂 / 后端外挂 / 事件配置覆盖三层。

没有绝对的第一名,只有与场景对齐的挂接方式。 选型时,把对方的名词翻译回 L1/L2/L3,再用第 7 节清单逐项核对——比比较口号更接近工程真相。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 1. 先把「二开」说清楚
    • 1.1 什么叫流程引擎的二开
    • 1.2 为什么产品名词各异,却是同一件事
  • 2. 三层挂接模型:L1 / L2 / L3
    • 2.1 这一能力的作用
    • 2.2 为什么它是重要评估指标
  • 3. 三层分别解决什么问题
    • 3.1 L1 交互层:人还在页面上时
    • 3.2 L2 服务层:进入引擎事务边界之后
    • 3.3 L3 配置 / 编排层:少写代码也能挂
  • 4. 流行引擎怎么实现:Java 阵营
    • 4.1 总对照(Java)
      • Camunda / Flowable / Activiti:同一套「BPMN 扩展点」思维
      • 该引擎:把三层做成并列入口
    • 4.2 Java 阵营怎么读表
  • 5. 流行引擎怎么实现:.NET 阵营
    • 5.1 总对照(.NET)
      • Elsa / Workflow Core:开发者编排优先
      • WorkflowEngine.NET / Slickflow:设计器与节点执行体
      • 该引擎:与该引擎同一套三层协议
    • 5.2 .NET 阵营怎么读表
  • 6. 同源实证:该引擎(Java)与该引擎(.NET)如何落在三层上
    • 6.1 概念映射
    • 6.2 L1:前端外挂(以该引擎 Vue3 为例)
    • 6.3 L2:后端外挂(.NET 与 Java 对照)
    • 6.4 L3:模板事件配置
    • 6.5 同源实现的启发(公平表述)
  • 7. 用三层模型做选型:一张检查清单
    • L1 交互层
    • L2 服务层
    • L3 配置编排层
    • 跨层原则
  • 8. 场景 × 层级:怎么选,而不是怎么站队
  • 9. 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档