1. 为什么选择Flowable与Spring Boot组合
在开始技术细节之前,有必要先理解为什么这个技术组合会成为企业级工作流开发的热门选择。Flowable作为Activiti的分支项目,继承了其优秀的流程引擎基因,同时进行了多项架构优化。而Spring Boot的约定优于配置理念,让开发者能够快速搭建生产级应用。
我最初接触这个组合是在2018年参与一个金融风控系统改造时。当时系统使用的是传统JBPM工作流,面临着性能瓶颈和扩展困难的问题。在技术选型阶段,我们对比了多个开源工作流引擎,最终Flowable以其轻量级架构和Spring生态的完美融合胜出。
1.1 Flowable的核心优势
Flowable 6.x版本在以下方面表现突出:
- BPMN 2.0标准支持:完全兼容国际标准,流程设计器生成的XML文件可移植性强
- 高性能运行时:采用命令模式设计,单个流程实例平均内存占用仅500KB左右
- 历史数据分级:支持配置历史数据的存储级别(无、活动、审计、全量)
- Spring集成:原生提供flowable-spring-boot-starter依赖
特别值得一提的是其异步执行器设计。在我们压力测试中,配置了10个异步线程的Flowable引擎,可以稳定处理每秒300+的简单审批流程实例。
1.2 Spring Boot的部署价值
Spring Boot为Flowable带来的关键价值点:
- 自动配置:自动创建ProcessEngine、注册Beans
- 内嵌服务器:无需额外部署Tomcat等容器
- 健康检查:自带/actuator/health端点监控引擎状态
- 简化依赖:starter机制解决版本冲突问题
这里有个实际案例:去年帮助某物流公司升级他们的运输调度系统时,从传统SSM架构迁移到Spring Boot+Flowable后,部署时间从原来的2小时缩短到15分钟,因为不再需要手动配置数据库连接池和事务管理器。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目初始化
2.1 基础环境要求
在开始编码前,请确保你的开发环境满足以下条件:
- JDK 1.8+(推荐Amazon Corretto 11)
- Maven 3.6+或Gradle 6.x
- IDE推荐IntelliJ IDEA(社区版即可)
- 数据库任选其一:
- H2(开发测试用)
- MySQL 5.7+(生产推荐)
- PostgreSQL 9.6+
重要提示:如果使用MySQL,需要设置默认隔离级别为READ-COMMITTED,否则可能出现流程实例锁问题:
sql复制SET GLOBAL transaction_isolation='READ-COMMITTED';
2.2 项目创建与依赖配置
使用Spring Initializr创建项目时,除了选择Web依赖外,需要额外添加:
xml复制<!-- Flowable核心依赖 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.0</version>
</dependency>
<!-- 数据库驱动(以MySQL为例) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
对于Gradle用户:
groovy复制implementation 'org.flowable:flowable-spring-boot-starter:6.7.0'
runtimeOnly 'mysql:mysql-connector-java'
2.3 关键配置详解
在application.properties中必须配置的项:
properties复制# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/flowable-demo?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Flowable配置
flowable.async-executor-activate=true # 启用异步执行器
flowable.database-schema-update=true # 自动更新数据库结构
flowable.history-level=audit # 历史记录级别
配置中的几个关键点说明:
database-schema-update:开发环境设为true,生产环境必须改为falsehistory-level:根据业务需求调整,全量记录(flowable)会影响性能async-executor-activate:高并发场景必须开启
3. 核心组件与自动配置原理
3.1 Spring Boot自动创建的Beans
启动项目后,Flowable自动配置会创建以下关键组件:
- ProcessEngine:流程引擎核心
- RepositoryService:管理流程定义
- RuntimeService:执行流程实例
- TaskService:处理用户任务
- HistoryService:访问历史数据
- ManagementService:引擎维护
可以通过简单的单元测试验证这些服务是否可用:
java复制@SpringBootTest
class FlowableServicesTest {
@Autowired
private RepositoryService repositoryService;
@Test
void testServicesInjection() {
assertNotNull(repositoryService);
assertEquals(0, repositoryService.createDeploymentQuery().count());
}
}
3.2 数据库表结构解析
Flowable会在首次启动时自动创建约60张表,主要分为以下几类:
- ACT_RE_*:存储静态资源(流程定义、部署信息)
- ACT_RU_*:运行时数据(执行实例、任务)
- ACT_HI_*:历史数据(已完成实例)
- ACT_GE_*:通用数据(二进制资源)
实际项目中我们遇到过表太多影响查询性能的问题。解决方案是:
- 定期归档ACT_HI_*表数据
- 为ACT_RU_TASK表的PROC_INST_ID_字段添加索引
- 禁用不需要的服务(如identityService)
4. 部署第一个流程
4.1 BPMN流程图设计
在resources/processes目录下创建leave-request.bpmn20.xml:
xml复制<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="http://flowable.org/bpmn">
<process id="leaveRequest" name="请假流程" isExecutable="true">
<startEvent id="start"/>
<userTask id="leaderApproval" name="主管审批"/>
<exclusiveGateway id="decision"/>
<sequenceFlow sourceRef="start" targetRef="leaderApproval"/>
<sequenceFlow sourceRef="leaderApproval" targetRef="decision"/>
<sequenceFlow sourceRef="decision" targetRef="hrRecord">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${days <= 3}]]>
</conditionExpression>
</sequenceFlow>
<userTask id="hrRecord" name="人事备案"/>
<sequenceFlow sourceRef="decision" targetRef="directorApproval">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${days > 3}]]>
</conditionExpression>
</sequenceFlow>
<userTask id="directorApproval" name="总监审批"/>
</process>
</definitions>
4.2 程序化部署方式
除了自动扫描resources/processes目录外,也可以通过代码动态部署:
java复制@Service
public class ProcessDeployer {
@Autowired
private RepositoryService repositoryService;
public void deployProcess(InputStream bpmnStream) {
Deployment deployment = repositoryService.createDeployment()
.addInputStream("leaveRequest.bpmn20.xml", bpmnStream)
.name("请假流程部署")
.deploy();
logger.info("部署成功,ID: {}", deployment.getId());
}
}
4.3 部署验证与问题排查
部署后常见问题及解决方案:
-
流程图无法解析:
- 检查XML命名空间是否正确
- 使用Flowable Modeler验证BPMN文件
-
流程定义未生效:
java复制// 查询已部署流程 List<ProcessDefinition> definitions = repositoryService .createProcessDefinitionQuery() .list(); -
自动建表失败:
- 检查数据库用户是否有CREATE TABLE权限
- 手动执行SQL脚本:flowable-db目录下的create脚本
5. 生产环境优化建议
5.1 性能调优配置
在生产环境中,建议调整以下参数:
properties复制# 异步执行器配置
flowable.async-executor.core-pool-size=10
flowable.async-executor.max-pool-size=50
flowable.async-executor.queue-size=1000
# 批量处理设置
flowable.job-executor.batch-size=100
flowable.job-executor.wait-time-in-millis=5000
# 禁用不需要的服务
flowable.idm.enabled=false
flowable.cmmn.enabled=false
5.2 高可用部署方案
对于关键业务系统,推荐以下架构:
code复制 [负载均衡]
|
-------------------------------
| |
[Spring Boot App1] [Spring Boot App2]
Flowable Engine Flowable Engine
| |
-------------------------------
|
[共享数据库]
(主从复制)
关键注意事项:
- 所有实例必须配置相同的async-executor.lock-owner
- 数据库连接池建议使用HikariCP
- 启用二级缓存:
java复制@Configuration public class FlowableConfig { @Bean public SpringProcessEngineConfiguration processEngineConfiguration( DataSource dataSource, PlatformTransactionManager transactionManager) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setDataSource(dataSource); config.setTransactionManager(transactionManager); config.setDatabaseSchemaUpdate("false"); config.setAsyncExecutorActivate(true); // 启用二级缓存 config.setProcessDefinitionCache(new DefaultDeploymentCache()); config.setProcessDefinitionInfoCache(new DefaultDeploymentCache()); return config; } }
5.3 监控与维护
建议集成Spring Boot Actuator进行健康监控:
properties复制management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
自定义Flowable健康指标:
java复制@Component
public class FlowableHealthIndicator implements HealthIndicator {
@Autowired
private ManagementService managementService;
@Override
public Health health() {
try {
String engineVersion = managementService.getProperties()
.get("engine.version");
return Health.up()
.withDetail("version", engineVersion)
.build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}
6. 常见问题解决方案
6.1 事务管理问题
在集成测试中经常遇到的事务问题:
java复制@Test
@Transactional // 必须添加事务注解
public void testCompleteTask() {
// 启动流程实例
ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveRequest");
// 查询并完成任务
Task task = taskService.createTaskQuery()
.processInstanceId(instance.getId())
.singleResult();
taskService.complete(task.getId());
// 验证流程状态
assertNull(runtimeService.createProcessInstanceQuery()
.processInstanceId(instance.getId())
.singleResult());
}
6.2 多数据源配置
当需要连接多个数据库时:
java复制@Configuration
public class FlowableDataSourceConfig {
@Bean
@ConfigurationProperties("flowable.datasource")
public DataSource flowableDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public PlatformTransactionManager flowableTransactionManager(
@Qualifier("flowableDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SpringProcessEngineConfiguration processEngineConfiguration(
@Qualifier("flowableDataSource") DataSource dataSource,
@Qualifier("flowableTransactionManager") PlatformTransactionManager transactionManager) {
SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
config.setDataSource(dataSource);
config.setTransactionManager(transactionManager);
// 其他配置...
return config;
}
}
6.3 自定义用户体系
集成已有用户系统的方案:
java复制public class CustomUserEntityManager implements UserEntityManager {
@Autowired
private UserRepository userRepository;
@Override
public User createNewUser(String userId) {
throw new UnsupportedOperationException();
}
@Override
public UserEntity findById(String userId) {
return convert(userRepository.findByUserId(userId));
}
private UserEntity convert(User user) {
UserEntity entity = new UserEntity();
entity.setId(user.getUserId());
entity.setFirstName(user.getRealName());
// 其他字段映射...
return entity;
}
}
配置自定义管理器:
java复制@Bean
public IdmEngineConfiguration idmEngineConfiguration() {
IdmEngineConfiguration config = new IdmEngineConfiguration();
config.setUserEntityManager(new CustomUserEntityManager());
return config;
}
在实际项目中,Spring Boot与Flowable的集成可以大幅提升工作流开发效率。我建议从简单流程开始,逐步掌握其核心机制,再根据业务需求进行深度定制。对于复杂业务流程,合理设计BPMN模型比编写大量补救代码更重要。
