BPM引擎系列(二) Activiti入门-老牌引擎还能打吗
Activiti入门——老牌引擎还能打吗系列第二篇Activiti 7 Spring Boot 集成实战从配置到跑通一个请假流程。一、ActivitiFlowableCamunda我懵了上篇咱们学完了BPMN信心满满地准备上手干活。结果一搜Java工作流引擎跳出来三个名字ActivitiFlowableCamunda更离谱的是搜Activiti的教程评论区总有人喊别用Activiti了用Flowable搜Flowable又有人说Camunda更专业。问题来了这三个到底啥关系Activiti这个老将还能不能打先上一张族谱图jBPM 3/4 │ ↓ ┌─────────────────┐ │ Activiti 5 │ ← 2010年Tom Baeyens 创建 │ (Alfresco) │ └────────┬────────┘ │ ┌──────────────┼──────────────┐ ↓ ↓ ↓ Activiti 6 Flowable 6 Camunda 7 (维护减少) (原班人马) (更专业) │ │ │ ↓ ↓ ↓ Activiti 7 Flowable 7 Camunda 8 (TOMATO) (活跃开发) (云原生)一句话总结Activiti 是老祖宗但 7 版本之后维护力度下降Flowable 是 Activiti 核心团队分家出来做的更活跃Camunda 也是 Activiti 分支定位更偏向企业级BPM平台那Activiti还能不能用能但更适合以下场景项目已经用了Activiti不想折腾迁移需求简单就是个审批流不需要复杂功能团队对Activiti比较熟悉好不纠结了咱们先把它跑起来再说二、Spring Boot 集成 Activiti2.1 创建项目用 Spring Initializr 创建一个 Spring Boot 项目或者直接在现有项目加依赖。pom.xml 核心依赖parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.18/version/parentpropertiesactiviti.version7.1.0.M6/activiti.version/propertiesdependencies!-- Spring Boot Web --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Activiti Spring Boot Starter --dependencygroupIdorg.activiti/groupIdartifactIdactiviti-spring-boot-starter/artifactIdversion${activiti.version}/version/dependency!-- H2 内存数据库演示用 --dependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdscoperuntime/scope/dependency/dependencies⚠️ 注意Activiti 7 的依赖不在 Maven Central需要从 Alfresco 仓库拉取。如果下载失败在 pom.xml 里加一下仓库配置repositoriesrepositoryidalfresco/idurlhttps://artifacts.alfresco.com/nexus/content/repositories/activiti-releases//url/repository/repositories2.2 配置文件application.ymlserver:port:8081spring:datasource:url:jdbc:h2:mem:activiti-db;DB_CLOSE_DELAY-1driver-class-name:org.h2.Driverusername:sapassword:# Activiti 核心配置activiti:# 自动更新数据库表结构database-schema-update:true# 自动检查并部署流程定义文件check-process-definitions:true# 流程定义文件存放位置process-definition-location-prefix:classpath:/processes/# 历史记录级别none/activity/audit/fullhistory-level:full关键配置说明配置项作用database-schema-update自动建表第一次运行必备check-process-definitions启动时自动扫描并部署流程history-level历史数据记录级别full记录最全2.3 流程定义文件把上篇画的请假流程BPMN文件放到src/main/resources/processes/目录下src/main/resources/processes/leave-process.bpmn20.xml文件内容核心片段完整版见配套源码?xml version1.0 encodingUTF-8?definitionsxmlnshttp://www.omg.org/spec/BPMN/20100524/MODELxmlns:activitihttp://activiti.org/bpmntargetNamespacehttp://example.org/leave-processprocessidleave-processname请假流程isExecutabletrue!-- 开始事件 --startEventidstartname提交申请/!-- 经理审批用户任务 --userTaskidmanager-approvalname经理审批activiti:assignee${managerId}/!-- 排他网关经理是否通过 --exclusiveGatewayidmanager-decisionname经理审批结果/!-- 驳回 → 结束 --endEventidmanager-reject-endname经理驳回/!-- 通过 → 检查天数 --exclusiveGatewayiddays-checkname天数3?/!-- 总监审批用户任务 --userTaskiddirector-approvalname总监审批activiti:assignee${directorId}/!-- HR备案服务任务自动执行 --serviceTaskidhr-recordnameHR备案activiti:expression${hrService.record(execution)}/!-- 发送邮件服务任务 --serviceTaskidsend-emailname发送通知邮件activiti:expression${emailService.send(execution)}/!-- 结束事件 --endEventidendname流程结束/!-- 连线 条件表达式... --/process/definitions注意命名空间Activiti 使用activiti:前缀的属性比如activiti:assignee、activiti:expression。三、Java代码启动流程、查待办、完成任务Activiti 的核心 API 就几个 Service记住它们Service作用RuntimeService启动流程、查询运行中的流程实例TaskService查询待办任务、完成任务RepositoryService部署流程定义、查询流程模型HistoryService查询历史数据已完成的流程3.1 启动流程RestControllerRequestMapping(/api/leave)publicclassLeaveController{AutowiredprivateRuntimeServiceruntimeService;PostMapping(/start)publicMapString,ObjectstartProcess(RequestParamStringapplicant,RequestParamStringmanagerId,RequestParamStringdirectorId,RequestParamIntegerdays){// 准备流程变量MapString,ObjectvariablesnewHashMap();variables.put(applicant,applicant);// 申请人variables.put(managerId,managerId);// 经理IDvariables.put(directorId,directorId);// 总监IDvariables.put(days,days);// 请假天数// 启动流程关键就这一行ProcessInstanceinstanceruntimeService.startProcessInstanceByKey(leave-process,variables);returnMap.of(processInstanceId,instance.getId(),message,请假流程已启动);}}关键点startProcessInstanceByKey(leave-process, ...)里的leave-process必须和 BPMN 文件里process idleave-process对应启动时传入的变量applicant、days等可以在整个流程中使用3.2 查询待办任务AutowiredprivateTaskServicetaskService;GetMapping(/tasks)publicListMapString,ObjectgetTasks(RequestParamStringassignee){// 查某个人的待办任务ListTasktaskstaskService.createTaskQuery().taskAssignee(assignee)// 按处理人过滤.list();returntasks.stream().map(task-Map.of(taskId,task.getId(),taskName,task.getName(),processInstanceId,task.getProcessInstanceId())).collect(Collectors.toList());}3.3 完成任务审批PostMapping(/complete)publicMapString,ObjectcompleteTask(RequestParamStringtaskId,RequestParamBooleanapproved){// 设置审批结果变量MapString,ObjectvariablesnewHashMap();variables.put(approved,approved);// true通过, false驳回variables.put(result,approved?通过:驳回);// 完成任务引擎会自动根据条件判断下一步去哪taskService.complete(taskId,variables);returnMap.of(taskId,taskId,message,approved?审批通过:已驳回);}这里有个坑要注意完成任务时传入的approved变量会被网关的条件表达式${approved true}或${approved false}使用。如果变量名写错了网关就不知道怎么走了流程会卡住。四、服务任务自动执行的逻辑流程里有两个服务任务HR备案、发送邮件不需要人处理系统自动执行。Activiti 里实现服务任务有几种方式方式1Spring Bean 表达式推荐Service(hrService)// Bean名称要和BPMN里的 ${hrService.record(execution)} 对应publicclassHrService{publicvoidrecord(DelegateExecutionexecution){// 从流程变量里取数据Stringapplicant(String)execution.getVariable(applicant);Integerdays(Integer)execution.getVariable(days);log.info(【HR备案】员工 {} 请假 {} 天已记录,applicant,days);// 实际这里可以调用HR系统的API}}BPMN里这样引用serviceTaskidhr-recordnameHR备案activiti:expression${hrService.record(execution)}/方式2JavaDelegate 接口ComponentpublicclassHrRecordDelegateimplementsJavaDelegate{Overridepublicvoidexecute(DelegateExecutionexecution){// 同样的逻辑}}BPMN里这样引用serviceTaskidhr-recordnameHR备案activiti:classcom.example.HrRecordDelegate/两种方式的区别表达式方式可以调用Spring管理的Bean支持传参更灵活JavaDelegate方式每次执行都创建新实例除非用Spring代理适合无状态逻辑推荐用表达式方式和Spring结合更紧密。五、跑起来完整测试流程5.1 启动应用mvn spring-boot:run启动日志里你会看到 Activiti 自动创建了几十张表Activiti Engine create activiti tables5.2 测试APIStep 1启动请假流程curl-XPOSThttp://localhost:8081/api/leave/start\-dapplicant小明\-dmanagerIdmanager-zhang\-ddirectorIddirector-li\-ddays5返回{processInstanceId:2501,message:请假流程已启动}Step 2经理查待办curlhttp://localhost:8081/api/leave/tasks?assigneemanager-zhang返回[{taskId:2505,taskName:经理审批,processInstanceId:2501}]Step 3经理审批通过curl-XPOSThttp://localhost:8081/api/leave/complete\-dtaskId2505\-dapprovedtrueStep 4总监查待办因为天数53需要总监审批curlhttp://localhost:8081/api/leave/tasks?assigneedirector-li返回[{taskId:2510,taskName:总监审批,processInstanceId:2501}]Step 5总监审批通过curl-XPOSThttp://localhost:8081/api/leave/complete\-dtaskId2510\-dapprovedtrue这时候日志会输出【HR备案】员工 小明 请假 5 天已记录到HR系统 【发送邮件】通知 小明你的请假申请已通过请查收流程结束六、数据库表速览Activiti 自动创建的表很多但核心就几类表前缀说明常用表ACT_RE_*流程定义RepositoryACT_RE_PROCDEF流程定义ACT_RU_*运行时数据RuntimeACT_RU_TASK待办任务ACT_RU_EXECUTION执行实例ACT_HI_*历史数据HistoryACT_HI_PROCINST历史流程实例ACT_HI_TASKINST历史任务ACT_ID_*身份数据IdentityACT_ID_USER用户ACT_ID_GROUP用户组一个查询小技巧想看当前有哪些待办任务直接查ACT_RU_TASKSELECTID_,NAME_,ASSIGNEE_,PROC_INST_ID_FROMACT_RU_TASK;七、Activiti 的优缺点优点✅ 历史悠久文档和教程多✅ API 设计简洁上手快✅ 和 Spring 集成成熟✅ 社区版免费缺点❌ Activiti 7 之后维护力度下降❌ 部分高级功能如动态表单、CMMN案例管理支持较弱❌ 没有内置的Web管理界面Camunda有Cockpit八、小结这篇咱们聊了Activiti 的身世——老牌引擎Flowable和Camunda的老祖宗Spring Boot 集成——加依赖、配YAML、放BPMN文件核心API——RuntimeService启动流程TaskService查待办/完成任务服务任务——用Spring Bean表达式实现自动逻辑完整测试——从启动到结束一步步跑通下一篇预告Activiti 原班人马分家做出来的Flowable到底升级了啥迁移成本高吗咱们代码里见分晓。配套源码本文完整源码位于02-activiti-demo/包含完整的pom.xml和application.yml请假流程 BPMN 定义REST API Controller服务任务实现单元测试3个场景全覆盖你在用 Activiti 吗遇到过什么坑欢迎交流
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2545129.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!