JeecgBoot与Activiti深度整合:从零构建企业级流程中心

张开发
2026/4/17 5:29:55 15 分钟阅读

分享文章

JeecgBoot与Activiti深度整合:从零构建企业级流程中心
1. 为什么选择JeecgBoot与Activiti整合企业级应用开发中工作流引擎就像人体的神经系统负责协调各个业务模块的运转。Activiti作为目前最成熟的开源工作流引擎之一它的BPMN 2.0标准支持、可视化流程设计能力和丰富的API接口使其成为企业流程管理的首选。而JeecgBoot这个基于SpringBoot的低代码平台就像给开发者配备了一个万能工具箱能快速生成基础业务代码。我在去年参与某大型制造企业的ERP系统升级时就采用了这套组合方案。当时客户需要在一个月内上线包含采购审批、生产报工等12个复杂流程的系统。传统开发方式至少需要3个月而通过JeecgBootActiviti的深度整合我们最终提前一周交付这让我深刻体会到这套技术栈的威力。两者的结合点主要体现在三个方面首先JeecgBoot自动生成的CRUD接口可以直接作为流程节点操作其次平台内置的权限体系能与Activiti的用户任务完美对接最重要的是通过低代码方式可以快速构建流程关联的业务表单省去了传统开发中表单与流程对接的繁琐工作。2. 环境搭建与基础配置2.1 项目初始化要点建议使用JeecgBoot 2.4.5以上版本这个版本开始对Activiti 5.22的兼容性更好。创建项目时要注意在pom.xml中需要排除Spring Security相关依赖否则会与Activiti自带的security模块冲突。我常用的初始化命令如下mvn archetype:generate -DgroupIdcom.yourcompany \ -DartifactIdworkflow-center \ -DarchetypeArtifactIdjeecg-boot-starter \ -DarchetypeVersion2.4.5数据库配置有个容易踩的坑Activiti需要独立的数据库schema。虽然可以和业务库共用但在生产环境建议分开。MySQL配置示例spring: datasource: master: url: jdbc:mysql://localhost:3306/biz_db activiti: url: jdbc:mysql://localhost:3306/act_db driver-class-name: com.mysql.jdbc.Driver2.2 核心依赖引入除了官方文档提到的activiti-spring-boot-starter外必须添加modeler模块才能使用可视化设计器。这里有个版本对齐的坑JeecgBoot内置的SpringBoot版本可能和Activiti默认依赖的不一致。我推荐这样锁定版本properties activiti.version5.22.0/activiti.version /properties dependencies dependency groupIdorg.activiti/groupId artifactIdactiviti-spring-boot-starter/artifactId version${activiti.version}/version exclusions exclusion groupIdorg.springframework.security/groupId artifactIdspring-security-*/artifactId /exclusion /exclusions /dependency dependency groupIdorg.activiti/groupId artifactIdactiviti-modeler/artifactId version${activiti.version}/version /dependency /dependencies3. 流程设计器深度整合3.1 汉化与界面改造原生的Activiti Modeler是全英文界面直接拿来用会被国内用户骂死。我从Activiti-explorer项目中提取了汉化资源主要包括三个部分editor-app下的i18n翻译文件、stencilset.json中的节点描述以及modeler.html的界面文字。具体操作将activiti-webapp-explorer2/src/main/webapp/editor-app/i18n复制到前端项目的public目录修改app-cfg.js中的配置项var ACTIVITI { CONFIG: { contextRoot: /service, i18nLocation: /i18n/zh-CN } };替换stencilset.json中的节点说明文本。有个细节要注意中文JSON文件需要保存为UTF-8 without BOM格式否则解析会出错。3.2 与业务表单的联动真正的企业流程离不开业务数据。我们在设计器中增加了关联表单的配置项核心原理是通过扩展Properties Panel实现的。关键代码片段public class CustomPropertiesParser implements ActivityBehavior { Override public void execute(DelegateExecution execution) { String formKey (String) execution.getVariable(formKey); // 通过JeecgBoot的API获取表单配置 JSONObject formConfig FormAPI.getConfig(formKey); execution.setVariable(formConfig, formConfig.toString()); } }在前端需要改造modeler.js在保存模型时注入表单关联信息Model.prototype.save function(callback) { var formData this.getFormData(); this.modelData.formConfig JSON.stringify(formData); // 原有保存逻辑... };4. 权限体系对接实战4.1 用户组映射策略JeecgBoot的RBAC权限模型需要与Activiti的CandidateGroup机制对接。我们的方案是通过拦截器自动同步Configuration public class ActivitiConfig extends ProcessEngineConfigurationImpl { Autowired private ISysUserService userService; PostConstruct public void initGroupSyncer() { identityService.createMembershipQuery() .list() .forEach(m - { String userId m.getUserId(); String groupId m.getGroupId(); // 同步到JeecgBoot权限体系 userService.addUserRole(userId, groupId); }); } }4.2 任务分配高级技巧除了常规的角色分配我们还实现了动态负责人机制。比如部门主管审批这种场景可以通过监听器动态设置public class DynamicAssigneeListener implements TaskListener { Override public void notify(DelegateTask task) { String deptId (String) task.getVariable(applyDept); // 调用JeecgBoot的部门服务获取主管 String manager sysDeptService.getManagerByDept(deptId); task.setAssignee(manager); } }在BPMN文件中配置userTask idleaderApprove name部门审批 extensionElements activiti:taskListener eventcreate classcom.your.pkg.DynamicAssigneeListener/ /extensionElements /userTask5. 生产环境调优经验5.1 多数据源配置陷阱Activiti的历史数据表ACT_HI_*在高并发下会成为性能瓶颈。我们的解决方案是使用ShardingSphere对历史表进行分片配置单独的数据库连接池spring: activiti: async-executor-activate: true history-level: audit shardingsphere: datasource: names: ds0,ds1 ds0: url: jdbc:mysql://db1:3306/act_hi ds1: url: jdbc:mysql://db2:3306/act_hi5.2 高可用部署方案对于关键业务流程我们实现了以下保障措施流程引擎集群部署使用Redis分布式锁异步任务失败重试机制流程实例监控看板Configuration public class ClusterConfig { Bean public ProcessEngineConfigurationImpl processEngineConfiguration( RedisLockRepository lockRepo) { SpringProcessEngineConfiguration config new SpringProcessEngineConfiguration(); config.setAsyncExecutorActivate(true); config.setAsyncExecutor(new RedisLockAsyncExecutor(lockRepo)); return config; } }记得在application.properties中添加spring.activiti.job-lock-prefixwf_lock: spring.activiti.async-executor-retry-wait5s6. 典型业务场景实现6.1 采购审批流程案例以常见的采购申请为例完整流程包括申请人填写→部门审批→财务复核→总经理核准→采购执行。在JeecgBoot中实现的关键步骤使用Online表单设计采购申请单在设计器中绘制BPMN流程图配置各节点的表单权限和操作按钮process idpurchase name采购流程 startEvent idstart/ userTask iddeptAudit name部门审核 activiti:formKeypurchase_form:edit/ sequenceFlow sourceRefstart targetRefdeptAudit/ !-- 其他节点... -- /process6.2 动态分支处理对于金额超过50万的采购需要额外增加CEO审批节点我们采用条件表达式实现exclusiveGateway iddecision/ sequenceFlow sourceRefdecision targetRefceoApprove conditionExpression xsi:typetFormalExpression ![CDATA[${amount 500000}]] /conditionExpression /sequenceFlow对应的Java服务任务public class AmountCheckDelegate implements JavaDelegate { Override public void execute(DelegateExecution execution) { Double amount (Double) execution.getVariable(amount); execution.setVariable(needCeoApprove, amount 500000); } }7. 调试与问题排查7.1 常见异常处理在整合过程中最常遇到的三个坑事务冲突解决方案是在Service层添加Transactional(propagationREQUIRES_NEW)类加载问题确保activiti-engine和jeecg-boot使用相同版本的mybatis缓存不一致调用repositoryService.activateProcessDefinitionById强制刷新7.2 日志监控方案我们基于JeecgBoot的日志模块扩展了流程监控功能Aspect Component public class ActivitiLogAspect { AfterReturning(execution(* org.activiti.engine..*.*(..))) public void logOperation(JoinPoint jp) { String method jp.getSignature().getName(); Object[] args jp.getArgs(); // 记录到业务日志表 sysLogService.saveActivitiLog(method, args); } }对应的日志查询接口SELECT * FROM sys_activiti_log WHERE process_instance_id ? ORDER BY create_time DESC8. 前端深度整合技巧8.1 流程设计器嵌入将Modeler集成到JeecgBoot前端框架的关键步骤在public目录下创建activiti-editor文件夹复制modeler.html和相关静态资源通过iframe嵌入到Vue组件template a-modal :visiblevisible cancelclose iframe :srceditorUrl stylewidth:100%;height:80vh/ /a-modal /template script export default { data() { return { editorUrl: /activiti-editor/modeler.html?modelIdthis.modelId } } } /script8.2 任务列表优化改造原有的待办列表增加流程可视化展示template a-table :columnscolumns template #action{record} a clickshowDiagram(record)流程图/a /template /a-table process-diagram :visiblediagramVisible :processInstanceIdcurrentId/ /template对应的流程图组件实现import { getDiagram } from /api/activiti export default { methods: { async showDiagram(record) { this.currentId record.processInstanceId const res await getDiagram(record.taskId) this.diagramSvg res.data this.diagramVisible true } } }

更多文章