首页
/ 从0到1精通Warm-Flow:国产轻量级工作流引擎实战指南

从0到1精通Warm-Flow:国产轻量级工作流引擎实战指南

2026-02-04 05:07:20作者:宣聪麟

引言:工作流引擎的选型困境与破局之道

你是否正在为项目寻找一款既轻量又强大的工作流引擎?面对市场上纷繁复杂的选择,是否感到无从下手?要么是过于庞大笨重,集成困难;要么是功能简陋,无法满足实际业务需求。今天,我们将带你深入了解一款国产优秀工作流引擎——Warm-Flow,它以简洁轻量、五脏俱全、灵活扩展性强的特点,正在成为众多开发者的首选。

读完本文,你将获得:

  • Warm-Flow工作流引擎的核心特性与优势解析
  • 从零开始的环境搭建与快速集成指南
  • 经典与仿钉钉双模式设计器的全面使用教程
  • 常见审批场景的实战案例与实现代码
  • 高级功能如监听器、表达式的应用技巧
  • 性能优化与扩展开发的最佳实践

1. Warm-Flow简介:国产工作流引擎的崛起

1.1 什么是Warm-Flow?

Warm-Flow是Dromara社区推出的一款国产工作流引擎(Workflow Engine),它以简洁轻量、功能全面、扩展性强为主要特点。作为一款面向开发者的中间件,Warm-Flow可以帮助你快速构建企业级的流程审批系统,如请假流程、报销审批、公文流转等各类业务流程。

1.2 Warm-Flow的核心优势

Warm-Flow相比其他工作流引擎,具有以下显著优势:

优势 说明
简洁轻量 核心仅7张表,代码量少,学习曲线平缓
易于集成 通过jar包快速集成,支持Spring和Solon框架
双模式设计器 原生支持经典模式和仿钉钉模式,满足不同用户习惯
功能全面 支持各种复杂审批操作和高级特性
灵活扩展 提供丰富的扩展点,可定制满足特定业务需求
多框架支持 兼容多种ORM框架和数据库
国产开源 完全开源免费,活跃的社区支持

1.3 技术架构概览

Warm-Flow的整体架构如下:

graph TD
    A[应用系统] --> B[Warm-Flow核心引擎]
    B --> C[流程定义管理]
    B --> D[流程实例运行]
    B --> E[任务分配与办理]
    B --> F[历史记录管理]
    B --> G[表单引擎]
    B --> H[权限控制]
    C --> I[设计器集成]
    D --> J[流程执行器]
    J --> K[节点处理器]
    J --> L[网关处理器]
    J --> M[监听器]
    J --> N[表达式引擎]
    B --> O[ORM适配器]
    O --> P[MyBatis]
    O --> Q[MyBatis-Plus]
    O --> R[JPA]
    O --> S[其他ORM框架]
    O --> T[数据库]

2. 环境搭建:从零开始的集成之旅

2.1 准备工作

在开始集成Warm-Flow之前,请确保你的开发环境满足以下要求:

  • JDK 8+
  • Maven 3.5+
  • 支持的数据库(MySQL、Oracle、PostgreSQL、SQL Server等)
  • Spring Boot 2.x/3.x 或 Solon 1.x/2.x(根据项目需求选择)

2.2 获取源代码

Warm-Flow的源代码托管在GitCode上,你可以通过以下命令克隆仓库:

git clone https://gitcode.com/dromara/warm-flow.git

2.3 数据库初始化

Warm-Flow需要一些基础表结构来存储流程定义、实例、任务等数据。根据你使用的数据库类型,执行相应的SQL脚本:

  1. 进入项目的sql目录,选择对应数据库的子目录
  2. 执行全量脚本warm-flow-all.sql

例如,对于MySQL数据库:

cd warm-flow/sql/mysql
# 执行warm-flow-all.sql脚本

如果你是升级版本,只需执行对应版本的升级脚本:

cd warm-flow/sql/mysql/v1-upgrade
# 执行对应版本的升级脚本,如warm-flow_1.8.0.sql

2.4 项目集成

2.4.1 Maven依赖

在你的项目pom.xml中添加Warm-Flow的依赖。根据你使用的ORM框架和Spring版本选择合适的starter:

Spring Boot + MyBatis-Plus

<dependency>
    <groupId>org.dromara.warm</groupId>
    <artifactId>warm-flow-mybatis-plus-sb-starter</artifactId>
    <version>最新版本</version>
</dependency>

Spring Boot 3 + MyBatis

<dependency>
    <groupId>org.dromara.warm</groupId>
    <artifactId>warm-flow-mybatis-sb3-starter</artifactId>
    <version>最新版本</version>
</dependency>

Solon + MyBatis-Plus

<dependency>
    <groupId>org.dromara.warm</groupId>
    <artifactId>warm-flow-mybatis-plus-solon-plugin</artifactId>
    <version>最新版本</version>
</dependency>

2.4.2 配置文件

application.ymlapplication.properties中添加Warm-Flow的配置:

warm:
  flow:
    # 是否开启调试模式
    debug: false
    # 流程设计器是否启用
    designer:
      enabled: true
    # ORM配置
    orm:
      type: mybatis-plus # 可选值:mybatis, mybatis-plus, jpa, easy-query, mybatis-flex
    # 多租户配置
    tenant:
      enabled: false
      column: tenant_id
    # 软删除配置
    logic-delete:
      enabled: false
      column: is_deleted
      value: 1
      not-value: 0

2.4.3 启动类配置

在Spring Boot启动类上添加@EnableWarmFlow注解:

import org.dromara.warm.flow.spring.annotation.EnableWarmFlow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableWarmFlow
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

3. 设计器使用:双模式流程设计详解

Warm-Flow提供了两种流程设计模式:经典模式和仿钉钉模式,满足不同用户的使用习惯。

3.1 设计器集成

Warm-Flow的设计器通过jar包形式集成到你的项目中,无需单独部署。集成后,你可以通过访问以下地址打开设计器:

http://localhost:8080/warm-flow/designer/index.html

3.2 经典模式设计器

经典模式采用传统的流程图设计方式,适合技术人员使用。主要元素包括:

  • 开始节点(Start Node):流程的起点
  • 结束节点(End Node):流程的终点
  • 任务节点(Task Node):需要用户处理的节点
  • 网关(Gateway):控制流程走向的节点,包括排他网关、并行网关等
  • 连接线(Sequence Flow):连接各个节点的线条
flowchart TD
    start[开始] --> task1[部门经理审批]
    task1 --> gateway{金额是否大于1000}
    gateway -->|是| task2[财务经理审批]
    gateway -->|否| task3[财务专员处理]
    task2 --> end[结束]
    task3 --> end

3.3 仿钉钉模式设计器

仿钉钉模式采用表单化的设计方式,更贴近业务人员的使用习惯,类似钉钉的审批流程设计。

主要功能包括:

  • 审批人设置:支持指定成员、角色、发起人自选等多种方式
  • 条件分支:根据条件设置不同的审批路径
  • 高级设置:包括审批方式(会签/或签)、超时设置、提醒规则等
graph LR
    A[发起人] --> B[直接上级审批]
    B --> C{金额>1000}
    C -->|是| D[财务总监审批]
    C -->|否| E[财务专员审批]
    D --> F[结束]
    E --> F

3.4 流程定义的导出与导入

设计完成后,你可以将流程定义导出为JSON格式保存,也可以导入已有的流程定义JSON文件。

导出的JSON示例:

{
  "flowId": "expense_approval",
  "flowName": "费用报销审批流程",
  "flowType": "NORMAL",
  "version": 1,
  "status": "ACTIVE",
  "nodes": [
    {
      "nodeId": "start",
      "nodeName": "开始",
      "nodeType": "START",
      "nextNodeId": "dept_manager"
    },
    {
      "nodeId": "dept_manager",
      "nodeName": "部门经理审批",
      "nodeType": "TASK",
      "assigneeType": "ROLE",
      "assigneeValue": "DEPT_MANAGER",
      "nextNodeId": "gateway"
    },
    // 更多节点...
  ],
  "conditions": [
    {
      "conditionId": "cond1",
      "nodeId": "gateway",
      "expression": "${amount > 1000}",
      "targetNodeId": "finance_manager"
    },
    // 更多条件...
  ]
}

4. 核心API:流程引擎的使用方法

Warm-Flow提供了简洁易用的API,帮助你快速实现流程的部署、启动、办理等操作。

4.1 FlowEngine核心接口

FlowEngine是Warm-Flow的核心接口,提供了流程操作的主要方法:

public interface FlowEngine {
    // 部署流程定义
    String deploy(FlowDeployDto flowDeployDto);
    
    // 启动流程实例
    String startInstance(FlowStartDto flowStartDto);
    
    // 办理任务
    void completeTask(FlowCompleteDto flowCompleteDto);
    
    // 退回任务
    void backTask(FlowBackDto flowBackDto);
    
    // 获取待办任务列表
    List<TaskDto> getTodoTasks(TaskQueryDto queryDto);
    
    // 获取流程实例详情
    InstanceDto getInstanceDetail(String instanceId);
    
    // 生成流程图URL
    String generateFlowImageUrl(String instanceId);
    
    // 更多方法...
}

4.2 流程部署与启动

@Autowired
private FlowEngine flowEngine;

// 部署流程
public String deployFlow() {
    FlowDeployDto deployDto = new FlowDeployDto();
    deployDto.setFlowName("费用报销流程");
    deployDto.setFlowKey("expense_approval");
    deployDto.setCategory("财务");
    // 流程定义JSON
    deployDto.setFlowJson(flowJson);
    return flowEngine.deploy(deployDto);
}

// 启动流程实例
public String startFlowInstance() {
    FlowStartDto startDto = new FlowStartDto();
    startDto.setFlowKey("expense_approval");
    startDto.setBusinessKey("EXP-20230914-001"); // 业务关联ID
    startDto.setInitiator("zhangsan"); // 发起人
    
    // 设置流程变量
    Map<String, Object> variables = new HashMap<>();
    variables.put("amount", 1500); // 报销金额
    variables.put("reason", "业务招待"); // 报销事由
    startDto.setVariables(variables);
    
    return flowEngine.startInstance(startDto);
}

4.3 任务办理与流转

// 办理任务
public void completeTask() {
    FlowCompleteDto completeDto = new FlowCompleteDto();
    completeDto.setTaskId("task123456"); // 任务ID
    completeDto.setOperator("lisi"); // 操作人
    completeDto.setAction("PASS"); // 操作:通过
    
    // 审批意见
    completeDto.setComment("同意报销,请财务处理");
    
    // 任务变量
    Map<String, Object> variables = new HashMap<>();
    variables.put("approveDate", new Date());
    completeDto.setVariables(variables);
    
    flowEngine.completeTask(completeDto);
}

// 获取待办任务
public List<TaskDto> getTodoTasks() {
    TaskQueryDto queryDto = new TaskQueryDto();
    queryDto.setAssignee("wangwu"); // 办理人
    return flowEngine.getTodoTasks(queryDto);
}

5. 实战案例:常见审批场景实现

5.1 请假流程

5.1.1 流程设计

请假流程通常包括以下步骤:

  1. 员工提交请假申请
  2. 直接上级审批
  3. 根据请假天数判断是否需要部门经理审批
  4. 人事部门备案
flowchart TD
    start[开始] --> submit[员工提交申请]
    submit --> leader[直接上级审批]
    leader --> gateway{天数>3天}
    gateway -->|是| manager[部门经理审批]
    gateway -->|否| hr[人事备案]
    manager --> hr
    hr --> end[结束]

5.1.2 实现代码

// 启动请假流程
public String startLeaveProcess(LeaveRequest request) {
    FlowStartDto startDto = new FlowStartDto();
    startDto.setFlowKey("leave_approval");
    startDto.setBusinessKey(request.getId().toString());
    startDto.setInitiator(request.getApplicantId());
    
    Map<String, Object> variables = new HashMap<>();
    variables.put("leaveType", request.getLeaveType());
    variables.put("days", request.getDays());
    variables.put("startDate", request.getStartDate());
    variables.put("endDate", request.getEndDate());
    variables.put("reason", request.getReason());
    
    startDto.setVariables(variables);
    return flowEngine.startInstance(startDto);
}

// 审批处理
public void approveLeave(String taskId, String userId, boolean approved, String comment) {
    FlowCompleteDto completeDto = new FlowCompleteDto();
    completeDto.setTaskId(taskId);
    completeDto.setOperator(userId);
    completeDto.setAction(approved ? "PASS" : "REJECT");
    completeDto.setComment(comment);
    
    flowEngine.completeTask(completeDto);
}

5.2 报销审批流程

5.2.1 流程设计

报销审批流程通常根据金额大小设置不同的审批级别:

  1. 员工提交报销申请
  2. 部门经理审批
  3. 根据金额判断是否需要财务经理审批
  4. 财务处理付款
flowchart TD
    start[开始] --> submit[员工提交报销申请]
    submit --> deptLeader[部门经理审批]
    deptLeader --> gateway{金额>10000}
    gateway -->|是| financeManager[财务经理审批]
    gateway -->|否| financeStaff[财务专员处理]
    financeManager --> financeStaff
    financeStaff --> end[结束]

5.2.2 实现代码

// 获取报销流程的待办任务
public List<TaskDto> getExpenseTodoTasks(String userId) {
    TaskQueryDto queryDto = new TaskQueryDto();
    queryDto.setAssignee(userId);
    queryDto.setFlowKey("expense_approval");
    return flowEngine.getTodoTasks(queryDto);
}

// 财务处理付款
public void processPayment(String taskId, String userId, String paymentNo) {
    FlowCompleteDto completeDto = new FlowCompleteDto();
    completeDto.setTaskId(taskId);
    completeDto.setOperator(userId);
    completeDto.setAction("PASS");
    
    Map<String, Object> variables = new HashMap<>();
    variables.put("paymentNo", paymentNo);
    variables.put("paymentDate", new Date());
    
    completeDto.setVariables(variables);
    flowEngine.completeTask(completeDto);
}

6. 高级特性:监听器与表达式应用

6.1 监听器(Listener)

监听器允许你在流程执行的特定事件发生时执行自定义逻辑。Warm-Flow支持多种类型的监听器:

  • 流程监听器:在流程实例的开始、结束等事件触发
  • 任务监听器:在任务创建、完成等事件触发
  • 执行监听器:在流程执行到特定节点时触发

6.1.1 监听器实现

@Component
public class ExpenseListener implements ExecutionListener {
    
    @Autowired
    private NotificationService notificationService;
    
    @Override
    public void notify(ExecutionListenerContext context) {
        // 获取流程变量
        Map<String, Object> variables = context.getVariables();
        String instanceId = context.getInstanceId();
        String nodeId = context.getNodeId();
        
        // 发送通知
        if ("dept_manager".equals(nodeId)) {
            String assignee = context.getTask().getAssignee();
            notificationService.send(assignee, "有新的报销单需要您审批", "流程实例ID: " + instanceId);
        }
    }
}

6.1.2 在设计器中配置监听器

在流程设计器中,选择需要添加监听器的节点,在属性面板中配置监听器:

  • 监听器类型:选择"执行监听器"
  • 事件类型:选择"节点进入"或"节点离开"
  • 监听器实现:选择自定义的监听器类

6.2 表达式(Expression)

Warm-Flow支持使用表达式来动态计算流程变量、条件判断等。

6.2.1 变量表达式

在流程定义中,可以使用变量表达式来动态设置任务办理人、条件判断等:

${assignee}  // 获取assignee变量
${initiator.deptManager}  // 获取发起人部门经理
${amount > 1000}  // 判断金额是否大于1000

6.2.2 SpEL表达式支持

Warm-Flow还支持Spring EL表达式,可以调用Bean的方法:

${@userService.getManager(initiator)}  // 调用userService的getManager方法
${@tool.calculateTax(amount)}  // 调用工具类计算税额

6.2.3 条件表达式应用

在网关的条件判断中使用表达式:

// 排他网关条件设置
ConditionDto condition = new ConditionDto();
condition.setNodeId("gateway1");
condition.setExpression("${amount > 1000}");
condition.setTargetNodeId("finance_manager");

7. 性能优化:大规模流程应用的调优策略

7.1 数据库优化

  • 索引优化:为常用查询字段建立索引,如流程实例ID、业务键、办理人等
  • 分表策略:对于历史数据,可以考虑按时间分表存储
  • 批量操作:使用批量插入、更新减少数据库交互次数

7.2 缓存策略

  • 流程定义缓存:缓存常用的流程定义,减少数据库查询
  • 流程变量缓存:对频繁访问的流程变量进行缓存
  • 缓存清理:合理设置缓存过期时间,避免内存溢出
@Configuration
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(30, TimeUnit.MINUTES)
                .maximumSize(1000));
        return cacheManager;
    }
}

7.3 异步处理

将非关键路径的操作改为异步执行,如通知发送、日志记录等:

@Async
public CompletableFuture<Void> sendNotificationAsync(String userId, String message) {
    // 发送通知逻辑
    return CompletableFuture.runAsync(() -> {
        // 异步执行的代码
    });
}

8. 扩展开发:自定义组件与适配器实现

8.1 自定义条件策略

Warm-Flow允许你扩展自定义的条件判断策略:

public class ConditionStrategyCustom extends AbstractConditionStrategy {
    
    @Override
    public String getType() {
        return "CUSTOM";  // 自定义条件类型
    }
    
    @Override
    public boolean condition(FlowParams flowParams, String express, Object val) {
        // 自定义条件判断逻辑
        // express: 条件表达式
        // val: 实际值
        return customCheck(express, val);
    }
    
    private boolean customCheck(String express, Object val) {
        // 实现自定义的条件检查逻辑
        return true;
    }
}

// 注册自定义条件策略
@Component
public class CustomConditionConfig {
    
    @Autowired
    private ConditionStrategyFactory conditionStrategyFactory;
    
    @PostConstruct
    public void init() {
        conditionStrategyFactory.register(new ConditionStrategyCustom());
    }
}

8.2 ORM适配器扩展

如果你需要使用Warm-Flow不直接支持的ORM框架,可以实现自定义的ORM适配器:

public class MyBatisFlexAdapter implements OrmAdapter {
    
    @Autowired
    private FlowDefinitionMapper flowDefinitionMapper;
    
    @Override
    public FlowDefinition selectByFlowKeyAndVersion(String flowKey, Integer version) {
        return flowDefinitionMapper.selectOne(
            Wrappers.<FlowDefinition>lambdaQuery()
                .eq(FlowDefinition::getFlowKey, flowKey)
                .eq(FlowDefinition::getVersion, version)
        );
    }
    
    // 实现其他必要的方法...
}

9. 常见问题与解决方案

9.1 集成问题

Q: 启动项目时提示找不到FlowEngine bean?
A: 请检查是否在Spring Boot启动类上添加了@EnableWarmFlow注解,或者是否正确引入了starter依赖。

Q: 设计器无法访问?
A: 检查配置项warm.flow.designer.enabled是否设置为true,以及是否有拦截器阻止了访问。

9.2 运行时问题

Q: 流程启动后没有生成任务?
A: 可能是流程定义中没有正确设置任务节点的办理人,请检查流程定义的节点配置。

Q: 条件分支没有按预期执行?
A: 检查条件表达式是否正确,以及流程变量是否按预期传递。可以开启debug模式查看详细日志。

9.3 性能问题

Q: 流程实例较多时,查询待办任务变慢?
A: 请确保在任务表的assignee字段上建立了索引,并考虑使用缓存优化。

10. 总结与展望

Warm-Flow作为一款国产轻量级工作流引擎,以其简洁易用、功能全面、扩展性强的特点,为开发者提供了一个优秀的工作流解决方案。通过本文的介绍,相信你已经对Warm-Flow有了全面的了解,并能够开始在项目中实践应用。

随着企业数字化转型的深入,工作流引擎的应用场景将越来越广泛。Warm-Flow团队也将持续迭代优化,未来计划支持更多高级特性,如:

  • AI辅助流程设计
  • 低代码平台集成
  • 更丰富的统计分析功能

如果你在使用过程中有任何问题或建议,欢迎加入Warm-Flow社区与我们交流。

附录:参考资源

  • 官方文档:https://warm-flow.dromara.org/
  • 源代码仓库:https://gitcode.com/dromara/warm-flow
  • 演示地址:http://www.hhzai.top (admin/admin123)
  • 测试案例:https://gitee.com/dromara/warm-flow-test
登录后查看全文
热门项目推荐
相关项目推荐