【第1章 环境搭建与项目结构解析】

第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 这样的大型项目,建议按照以下顺序阅读源码:

第一阶段:核心入口

  1. ProcessEngines.java - 流程引擎入口
  2. ProcessEngine.java - 流程引擎接口
  3. ProcessEngineImpl.java - 流程引擎实现
  4. ProcessEngineConfiguration.java - 配置类

第二阶段:服务层

  1. RepositoryService.java - 仓库服务
  2. RuntimeService.java - 运行时服务
  3. TaskService.java - 任务服务

第三阶段:核心执行

  1. Agenda.java - 执行调度器
  2. ExecutionEntity.java - 执行实体
  3. 各种 ActivityBehavior - 活动行为实现

第四阶段:持久化

  1. EntityManager 相关类
  2. 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 提供了很多有用的功能来帮助阅读源码:

  1. 快速导航
  • Ctrl + N - 查找类
  • Ctrl + Shift + N - 查找文件
  • Ctrl + Alt + B - 跳转到实现
  • Ctrl + H - 查看类继承层次
  1. 结构视图

打开 View → Tool Windows → Structure,可以看到类的结构

  1. 调用层次

在方法上按 Ctrl + Alt + H,可以查看方法的调用层次

  1. 书签

在重要的代码行上按 F11 添加书签,方便快速跳转

本章小结

在本章中,我们完成了:

  1. 从 GitHub 克隆了 Flowable 7.2 源码
  2. 了解了 Maven 项目结构
  3. 配置了 IDEA 开发环境
  4. 分析了核心模块架构和依赖关系
  5. 创建了第一个 Flowable 应用
  6. 学习了源码阅读方法和调试技巧
    下一章预告: 第 2 章我们将深入探讨 Flowable 的核心架构设计,包括 ProcessEngine 体系、7 大核心服务、命令模式与拦截器链等重要内容。

实践建议:

  • 在继续阅读之前,务必先完成环境搭建
  • 尝试自己运行一下示例代码
  • 试着在关键位置设置断点,单步调试一下
  • 熟悉一下项目的目录结构,为后续章节做好准备
相关推荐
a***72891 小时前
Java进阶(ElasticSearch的安装与使用)
java·elasticsearch·jenkins
Java成神之路-1 小时前
面试题:Spring AOP底层实现原理
java·spring aop
Python私教1 小时前
如意Agent日志系统重构:从 print() 大海捞针到结构化可观测性栈
java·前端·重构
jieyucx1 小时前
Go 零基础数据结构:顺序表(像「排抽屉」一样学增删改查)
java·数据结构·golang
曦夜日长1 小时前
C++ STL容器string(一):string的变量细节、默认函数的认识以及常用接口的使用
java·开发语言·c++
北山有鸟2 小时前
IS_ERR 判断出错后,再用 PTR_ERR 把它强制转换回 int 型的错误码作为函数的返回值。
java·开发语言
程序员老邢2 小时前
【产品底稿 11】架构规整收官:从混乱到清晰,工程结构、表命名、模块分层一次性定型
后端·架构·springboot·产品底稿·架构规整·模块分层·数据库规范
phltxy2 小时前
深度解析:Spring Cloud Gateway 从入门到实战
java·开发语言
HAPPY酷2 小时前
从Public到Private:UE5 C++类创建路径差异全解析
java·c++·ue5