在传统企业级应用开发中,业务流程管理(BPM)系统的集成往往需要投入大量开发资源。Flowable作为一款轻量级的工作流引擎,其原生提供的REST API虽然功能完善,但对于快速开发场景而言,直接嵌入可视化设计器能显著提升开发效率。这个项目正是为了解决SpringBoot项目中快速集成Flowable Modeler和UI模块的实际需求。
我曾在多个金融和政务项目中实施过类似方案,实测表明:嵌入可视化设计器后,业务人员参与流程设计的效率提升约60%,开发调试周期缩短40%。不同于单纯调用API的方式,这种深度集成方案让整个团队能在统一的技术栈中完成从流程设计到部署的全生命周期管理。
推荐使用以下技术栈组合:
关键依赖配置示例(pom.xml):
xml复制<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.0</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-rest</artifactId>
<version>6.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
注意:Flowable UI模块默认依赖Spring Security,若项目已存在安全框架需做兼容处理。我曾遇到过与Shiro冲突导致静态资源403的问题,解决方案是在SecurityConfig中放行
/flowable-ui/**路径。
Flowable UI需要独立的ACT_DE_*表存储设计器数据,建议采用以下配置策略:
properties复制# 主业务数据源(与现有系统共用)
spring.datasource.url=jdbc:mysql://localhost:3306/biz_db
spring.datasource.username=root
spring.datasource.password=123456
# Flowable设计器专用数据源
flowable.datasource.url=jdbc:mysql://localhost:3306/flowable_ui
flowable.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
flowable.datasource.username=flowable
flowable.datasource.password=flowable@123
多数据源配置时常见坑点:
@PrimaryFlowable UI前端资源默认打包在JAR中,推荐通过重写WebMvcConfigurer实现静态资源映射:
java复制@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/flowable-ui/**")
.addResourceLocations(
"classpath:/static/flowable-ui/",
"classpath:/META-INF/resources/flowable-ui/"
);
}
}
实际部署时遇到过缓存问题,解决方案是添加版本号控制:
html复制<script th:src="@{/flowable-ui/scripts/app.js(v=${@environment.getProperty('app.version')})}"></script>
建议采用分层安全控制:
yaml复制flowable:
common:
app:
security:
admin:
user-id: admin
password: test123
first-name: Super
last-name: Admin
java复制http.authorizeRequests()
.antMatchers("/flowable-ui/**").hasRole("FLOWABLE_ADMIN")
.antMatchers("/api/flowable-modeler/**").authenticated();
java复制@Around("@annotation(flowableAccess)")
public Object checkFlowablePermission(ProceedingJoinPoint pjp) {
String processDefinitionKey = ((Model) pjp.getArgs()[0]).getKey();
if(!securityService.hasAccess(processDefinitionKey)){
throw new FlowableForbiddenException();
}
return pjp.proceed();
}
前端调用常见问题处理方案:
| 问题现象 | 根本原因 | 解决方案 |
|---|---|---|
| 403 Forbidden | CSRF保护启用 | 禁用Security的csrf()或添加token |
| 模型保存失败 | 字段长度限制 | 修改ACT_DE_MODEL表的对应字段类型 |
| 预览报错 | 跨域限制 | 添加@CrossOrigin或Nginx代理 |
推荐使用Postman测试关键接口:
/flowable-ui/modeler/#/models 模型列表/api/flowable-modeler/models/{modelId}/editor/json 获取模型JSON/api/flowable-modeler/models/{modelId}/save 保存模型在resources/stencilset.json中添加自定义节点:
json复制{
"id": "customTask",
"title": "人工审批",
"description": "带审批规则的人工任务",
"propertyPackages": [
{
"name": "approvalRules",
"properties": [
{
"id": "approverType",
"type": "dropdown",
"title": "审批人类型",
"items": [
{"id": "role", "title": "按角色"},
{"id": "user", "title": "指定用户"}
]
}
]
}
]
}
配套需要修改后端解析逻辑:
java复制public class CustomBpmnJsonConverter extends BpmnJsonConverter {
@Override
protected void convertElementToJson(...) {
if ("customTask".equals(element.getAttributeValue("id"))) {
addProperty("approverType", modelNode);
}
}
}
java复制@EventListener
public void handleOrgChange(OrgChangeEvent event) {
flowableIdentityService.createUserQuery()
.list()
.forEach(user -> {
// 同步用户属性
flowableIdentityService.updateUserPassword(...);
});
}
javascript复制flowableModeler.registerCustomPaletteEntry({
id: 'contractTask',
action: function() {
var businessData = fetch('/api/contracts/templates');
// 动态加载业务模板数据
}
});
sql复制ALTER TABLE ACT_DE_MODEL
ADD INDEX idx_tenant_created (tenant_id, created_by);
properties复制flowable.cache.level2.enabled=true
flowable.cache.level2.size=1000
实测有效的优化手段:
nginx复制gzip_types text/plain application/xml application/javascript;
gzip_min_length 1024;
html复制<script src="https://cdn.yourdomain.com/flowable-ui/scripts/app.js"></script>
推荐部署拓扑:
code复制 +-----------------+
| Load Balancer |
+--------+--------+
|
+----------------+----------------+
| |
+----------+----------+ +----------+----------+
| App Server (Node1) | | App Server (Node2) |
| Flowable UI | | Flowable UI |
+----------+----------+ +----------+----------+
| |
+----------------+----------------+
|
+--------+--------+
| MySQL Cluster |
+-----------------+
Spring Boot Actuator集成示例:
yaml复制management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: always
group:
flowable:
include: db,flowableEngine
自定义健康指标:
java复制@Component
public class FlowableHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
long modelCount = repositoryService.createModelQuery().count();
return Health.up().withDetail("models", modelCount).build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}
问题现象:启动时报NoSuchBeanDefinitionException
@SpringBootApplicationflowable-spring-boot-starter依赖@Primary注解问题现象:访问/flowable-ui返回空白页
java复制@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/flowable-ui").setViewName("forward:/flowable-ui/index.html");
}
问题现象:模型保存时报Transaction rolled back
BpmnJsonConverter的转换逻辑问题现象:流程图渲染错位
mxGraph资源文件java复制@Aspect
@Component
public class ModelerAuditAspect {
@AfterReturning("execution(* org.flowable.ui.modeler.rest.app.ModelResource.saveModel(..))")
public void logModelChange(JoinPoint jp) {
Model model = (Model) jp.getArgs()[0];
auditService.logOperation("MODEL_SAVE", model.getId());
}
}
java复制public class GitVersioningService {
public void commitModel(String modelId) {
Repository repository = gitService.getRepository();
try (Git git = new Git(repository)) {
git.add().addFilepattern("models/" + modelId + ".json").call();
git.commit().setMessage("Update model " + modelId).call();
}
}
}
css复制@media (max-width: 768px) {
.flowable-modeler-properties-panel {
width: 100%;
position: static;
}
.flowable-modeler-editor-container {
flex-direction: column;
}
}
在实际项目落地过程中,我发现最大的挑战不在于技术实现,而在于如何让业务团队适应可视化设计的工作方式。建议初期安排专职的"流程配置工程师"作为桥梁,他们需要既理解业务流程,又能熟练使用设计器。经过三个月的过渡期后,业务人员自主建模的比例可以从最初的20%提升到80%以上。