第1章 环境搭建与项目结构解析
在开始深入学习 Flowable 7.2 源码之前,我们首先需要搭建好开发环境,熟悉项目结构。本章将引导你完成从源码获取、编译到第一个示例程序运行的全过程。
1.1 源码获取与编译
1.1.1 从 GitHub 克隆 Flowable 7.2 源码
Flowable 项目托管在 GitHub 上,我们可以通过 Git 命令克隆源码仓库:
# 克隆 Flowable 源码仓库
git clone -b flowable-release-7.2.0 https://github.com/flowable/flowable-engine.git
# 进入项目目录
cd flowable-engine
如果你已经有一个本地仓库(比如当前工作目录 d:\git\flowable-engine),可以直接使用:
# 确保你的代码是最新的
git pull origin main
1.1.2 Maven 项目结构概览
让我们先看看 Flowable 项目的目录结构:
flowable-engine/
├── .github/ # GitHub 相关配置
(CI/CD、Issue 模板等)
├── .mvn/ # Maven Wrapper 配
置
├── distro/ # 分发包配置
├── docker/ # Docker 镜像配置
├── docs/ # 文档
├── ide-settings/ # IDE 配置(IDEA、
Eclipse)
├── modules/ # 核心模块(最重要的部
分!)
├── qa/ # 质量保证相关配置
├── scripts/ # 脚本文件
├── tooling/ # 工具相关
├── pom.xml # 根 pom.xml
├── mvnw # Maven Wrapper
(Unix)
└── mvnw.cmd # Maven Wrapper
(Windows)
其中,modules/ 目录是整个项目的核心,包含了所有功能模块。
1.1.3 源码编译与环境配置(JDK 17+)
Flowable 7.2 要求 JDK 17 或更高版本。让我们先检查一下 Java 环境:
java -version
确保输出显示的是 JDK 17+。如果没有,需要先安装 JDK 17。
接下来,使用 Maven 编译项目。Flowable 提供了 Maven Wrapper,我们可以直接使用:
Windows 系统:
mvnw.cmd clean install -DskipTests
Linux/Mac 系统:
./mvnw clean install -DskipTests
注意事项:
- -DskipTests 参数可以跳过测试,加快编译速度
- 首次编译可能需要较长时间,因为需要下载所有依赖
- 如果遇到网络问题,可以配置 Maven 镜像源(如阿里云镜像)
1.1.4 IDEA 项目导入与配置
步骤 1:导入项目
打开 IntelliJ IDEA,选择 File → Open,选择 flowable-engine 目录。IDEA 会自动识别这是一个 Maven 项目,并开始导入依赖。
步骤 2:配置 Maven
确保 IDEA 使用正确的 Maven 设置:
- 打开 File → Settings(Windows)或 IntelliJ IDEA → Preferences(Mac)
- 导航到 Build, Execution, Deployment → Build Tools → Maven
- 配置 Maven home directory(可以使用项目自带的 Maven Wrapper)
- 配置 User settings file(如果使用自定义配置)
步骤 3:配置 JDK
确保项目使用 JDK 17+:
- 打开 File → Project Structure
- 在 Project 页面,设置 SDK 为 JDK 17+
- 在 Modules 页面,确保所有模块的 Language level 为 17+
步骤 4:启用注解处理
Flowable 使用了一些注解处理,需要在 IDEA 中启用:
- 打开 File → Settings → Build, Execution, Deployment → Compiler → Annotation Processors
- 勾选 Enable annotation processing
1.2 项目模块架构详解
1.2.1 核心模块梳理
让我们深入看看 modules/ 目录下的核心模块:
| 模块名称 | 主要职责 |
|---|---|
| flowable-engine | 核心引擎 ,包含 BPMN 流程引擎的主要实现 |
| flowable-engine-common | 通用组件 ,提供引擎共享的基础功能 |
| flowable-engine-common-api | 通用 API ,定义了公共接口 |
| flowable-bpmn-model | BPMN 模型 ,定义 BPMN 2.0 元素的 Java 模型 |
| flowable-bpmn-converter | BPMN 转换器 ,负责 BPMN XML 与 Java 模型之间的转换 |
| flowable-process-validation | 流程验证器 ,验证流程定义的正确性 |
| flowable-image-generator | 图像生成器 ,生成流程定义的可视化图片 |
| flowable-task-service | 任务服务 ,处理用户任务相关功能 |
| flowable-variable-service | 变量服务 ,处理流程变量 |
| flowable-job-service | 作业服务 ,处理定时任务和异步作业 |
| flowable-idm-engine | 身份管理 ,处理用户、组等身份数据 |
| flowable-cmmn-engine | CMMN 引擎 ,处理案例管理(可选模块) |
| flowable-dmn-engine | DMN 引擎 ,处理决策表(可选模块) |
| flowable-event-registry | 事件注册表 ,处理事件驱动架构 |
| flowable-spring | Spring 集成 ,与 Spring 框架集成 |
| flowable-spring-boot | Spring Boot 集成 ,提供 Spring Boot 自动配置 |
| flowable-rest | REST API ,提供 REST 接口 |
1.2.2 模块依赖关系分析
让我们通过 flowable-engine 的 pom.xml 来理解模块依赖关系(你可以在 d:\git\flowable-engine\modules\flowable-engine\pom.xml 找到这个文件):
<dependencies>
<!-- 基础模块 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine-common</
artifactId>
</dependency>
<!-- BPMN 相关 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-bpmn-converter</
artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-process-validati
on</artifactId>
</dependency>
<!-- 服务模块 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-variable-service
</artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-task-service</
artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-job-service</
artifactId>
</dependency>
</dependencies>
从这里可以看出,flowable-engine 是核心模块,它依赖于:
- 通用基础模块
- BPMN 解析和验证模块
- 各种服务模块(变量、任务、作业等)
1.2.3 核心功能模块职责划分
让我们用一张架构图来展示 Flowable 的模块关系:
基础组件层(Foundation)
核心服务模块(Core Services)
引擎服务层(Engine Services)
应用层(Application)
flowable-rest
flowable-spring-boot
flowable-cdi
flowable-engine
flowable-cmmn-engine
flowable-dmn-engine
task-service
variable-service
job-service
identitylink-service
flowable-engine-common
bpmn-model
bpmn-converter
...
1.3 启动第一个 Flowable 应用
1.3.1 最小化配置示例
让我们创建一个最简单的 Flowable 应用程序。在 IDEA 中创建一个新的 Java 类:
package org.flowable.example;
import org.flowable.engine.*;
import org.flowable.engine.repository.
Deployment;
import org.flowable.engine.runtime.
ProcessInstance;
import org.flowable.task.api.Task;
import java.util.List;
public class FirstFlowableApp {
public static void main(String[] args) {
// 1. 创建流程引擎
ProcessEngine processEngine =
ProcessEngines.
getDefaultProcessEngine();
// 2. 获取各种服务
RepositoryService repositoryService
= processEngine.getRepositoryService
();
RuntimeService runtimeService =
processEngine.getRuntimeService();
TaskService taskService =
processEngine.getTaskService();
// 3. 部署流程定义(简单的请假流程)
Deployment deployment =
repositoryService.createDeployment()
.addClasspathResource
("leave-process.bpmn20.xml")
.name("请假流程")
.deploy();
System.out.println("流程部署成功,部署
ID: " + deployment.getId());
// 4. 启动流程实例
ProcessInstance processInstance =
runtimeService.
startProcessInstanceByKey
("leaveProcess");
System.out.println("流程实例启动成功,实
例ID: " + processInstance.getId());
// 5. 查询待办任务
List<Task> tasks = taskService.
createTaskQuery()
.taskAssignee("zhangsan")
.list();
System.out.println("张三的待办任务数量
: " + tasks.size());
for (Task task : tasks) {
System.out.println("任务ID: " +
task.getId() + ", 任务名称: " +
task.getName());
}
// 6. 关闭流程引擎
processEngine.close();
}
}
1.3.2 ProcessEngine 初始化流程
现在,让我们深入源码看看 ProcessEngines.getDefaultProcessEngine() 是如何工作的。
首先,查看 ProcessEngines 类(位置:modules/flowable-engine/src/main/java/org/flowable/engine/ProcessEngines.java):
public static ProcessEngine
getDefaultProcessEngine() {
return getProcessEngine(NAME_DEFAULT);
}
public static ProcessEngine getProcessEngine
(String processEngineName) {
if (!isInitialized()) {
init();
}
return processEngines.get
(processEngineName);
}
init() 方法会尝试从 flowable.cfg.xml 配置文件创建 ProcessEngine。
接下来,看看 ProcessEngineImpl 的构造函数(位置:modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessEngineImpl.java):
public ProcessEngineImpl
(ProcessEngineConfigurationImpl
processEngineConfiguration) {
this.processEngineConfiguration =
processEngineConfiguration;
this.name = processEngineConfiguration.
getEngineName();
this.repositoryService =
processEngineConfiguration.
getRepositoryService();
this.runtimeService =
processEngineConfiguration.
getRuntimeService();
this.historicDataService =
processEngineConfiguration.
getHistoryService();
// ... 初始化其他服务
// 执行数据库 schema 管理
if (processEngineConfiguration.
getSchemaManagementCmd() != null) {
commandExecutor.execute
(processEngineConfiguration.
getSchemaCommandConfig(),
processEngineC
onfiguration.
getSchemaManag
ementCmd());
}
// 注册流程引擎
ProcessEngines.registerProcessEngine
(this);
}
1.3.3 数据库表结构解析
Flowable 启动时会自动创建或更新数据库表。让我们看看主要的表:
ACT_RE_* Repository (仓库):存储流程定义、部署等静态信息 ACT_RU_* Runtime (运行时):存储流程实例、任务、变量等运行时数据 ACT_ID_* Identity (身份):存储用户、组等身份信息 ACT_HI_* History (历史):存储历史数据,如已完成的流程实例、任务等 ACT_GE_* General (通用):通用数据,如字节数组、属性等
| 表名前缀 | 说明 |
|---|---|
| ACT_RE_* | Repository (仓库):存储流程定义、部署等静态信息 |
| ACT_RU_* | Runtime (运行时):存储流程实例、任务、变量等运行时数据 |
| ACT_ID_* | Identity (身份):存储用户、组等身份信息 |
| ACT_HI_* | History (历史):存储历史数据,如已完成的流程实例、任务等 |
| ACT_GE_* | General (通用):通用数据,如字节数组、属性等 |
主要表的详细说明:
- ACT_RE_PROCDEF :流程定义表
- ACT_RU_EXECUTION :执行实例表
- ACT_RU_TASK :任务表
- ACT_RU_VARIABLE :变量表
- ACT_HI_PROCINST :历史流程实例表
- ACT_HI_TASKINST :历史任务表
1.4 源码阅读方法与调试技巧
1.4.1 推荐的源码阅读顺序
对于 Flowable 这样的大型项目,建议按照以下顺序阅读源码:
第一阶段:核心入口
- ProcessEngines.java - 流程引擎入口
- ProcessEngine.java - 流程引擎接口
- ProcessEngineImpl.java - 流程引擎实现
- ProcessEngineConfiguration.java - 配置类
第二阶段:服务层
- RepositoryService.java - 仓库服务
- RuntimeService.java - 运行时服务
- TaskService.java - 任务服务
第三阶段:核心执行
- Agenda.java - 执行调度器
- ExecutionEntity.java - 执行实体
- 各种 ActivityBehavior - 活动行为实现
第四阶段:持久化
- EntityManager 相关类
- MyBatis Mapper 文件
1.4.2 断点调试技巧
技巧 1:在关键入口设置断点
建议在以下位置设置断点:
- ProcessEngineImpl 构造函数 - 观察引擎初始化
- RuntimeService.startProcessInstance() - 观察流程启动
- TaskService.complete() - 观察任务完成
- Agenda.planOperation() - 观察执行调度
技巧 2:使用条件断点
在调试时,可以使用条件断点来过滤无关的执行:
"leaveProcess".equals(processDefinitionKey)
技巧 3:观察 ExecutionTree
Flowable 提供了 ExecutionTreeUtil 类来可视化执行树。在调试时,可以在表达式求值窗口执行:
org.flowable.engine.debug.ExecutionTreeUtil.
buildExecutionTree(execution)
1.4.3 日志配置与关键日志解读
Flowable 使用 SLF4J 作为日志框架。你可以在 src/test/resources 下找到 log4j.properties 示例。
关键日志配置:
# 开启 Flowable 引擎日志
log4j.logger.org.flowable.engine=DEBUG
# 开启 SQL 日志
log4j.logger.org.flowable.engine.impl.
persistence.entity=DEBUG
# 开启 SQL 语句输出
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
关键日志解读:
当流程执行时,你会看到类似这样的日志:
DEBUG - Executing agenda operation
ContinueProcessOperation
DEBUG - Leaving activity 'startEvent'
DEBUG - Taking transition 'flow1'
DEBUG - Entering activity 'userTask1'
这些日志可以帮助你理解流程执行的路径。
1.4.4 使用 IDEA 的强大功能
IDEA 提供了很多有用的功能来帮助阅读源码:
- 快速导航
- Ctrl + N - 查找类
- Ctrl + Shift + N - 查找文件
- Ctrl + Alt + B - 跳转到实现
- Ctrl + H - 查看类继承层次
- 结构视图
打开 View → Tool Windows → Structure,可以看到类的结构
- 调用层次
在方法上按 Ctrl + Alt + H,可以查看方法的调用层次
- 书签
在重要的代码行上按 F11 添加书签,方便快速跳转
本章小结
在本章中,我们完成了:
- 从 GitHub 克隆了 Flowable 7.2 源码
- 了解了 Maven 项目结构
- 配置了 IDEA 开发环境
- 分析了核心模块架构和依赖关系
- 创建了第一个 Flowable 应用
- 学习了源码阅读方法和调试技巧
下一章预告: 第 2 章我们将深入探讨 Flowable 的核心架构设计,包括 ProcessEngine 体系、7 大核心服务、命令模式与拦截器链等重要内容。
实践建议:
- 在继续阅读之前,务必先完成环境搭建
- 尝试自己运行一下示例代码
- 试着在关键位置设置断点,单步调试一下
- 熟悉一下项目的目录结构,为后续章节做好准备