保姆级教程:用IDEA插件Flowable BPMN visualizer画请假流程图,再配Spring Boot跑起来
零基础玩转Flowable:IDEA插件+Spring Boot实现可视化请假审批系统
在当今企业级应用开发中,业务流程管理(BPM)已成为提升运营效率的核心组件。想象一下这样的场景:当员工提交请假申请后,系统能自动流转至直属主管审批,再根据结果决定是否递交给部门经理,最终实时反馈处理结果给申请人——这种自动化的工作流正是Flowable流程引擎的拿手好戏。不同于传统的手工编码审批逻辑,使用BPMN2.0标准可视化建模,开发者可以像搭积木一样构建复杂业务流程,而Spring Boot的整合让这一切变得前所未有的简单。
1. 开发环境准备与项目初始化
1.1 必备工具链配置
工欲善其事,必先利其器。我们需要准备以下开发环境:
- IntelliJ IDEA Ultimate版:社区版缺少BPMN插件支持
- JDK 1.8+:Flowable对Java8有最佳兼容性
- MySQL 5.7+:用于存储流程运行时数据
- Flowable BPMN Visualizer插件:在IDEA的Plugin Marketplace中搜索安装
提示:安装插件后需重启IDEA才能激活BPMN设计器功能
1.2 Spring Boot项目骨架搭建
使用Spring Initializr创建项目时,需特别注意依赖选择:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.flowable</groupId> <artifactId>flowable-spring-boot-starter</artifactId> <version>6.7.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>数据库配置建议采用隔离的schema,避免与业务表混用:
spring: datasource: url: jdbc:mysql://localhost:3306/flowable_demo?useSSL=false&serverTimezone=Asia/Shanghai username: flow_user password: Flow@1234 driver-class-name: com.mysql.cj.jdbc.Driver启动项目后,检查控制台日志,应该能看到Flowable自动创建的47张表,这些表分为五大类:
| 表类型 | 数量 | 作用描述 |
|---|---|---|
| ACT_RE_* | 5 | 存储流程定义和部署资源 |
| ACT_RU_* | 8 | 运行时流程实例数据 |
| ACT_HI_* | 8 | 历史流程实例数据 |
| ACT_ID_* | 5 | 身份认证相关表 |
| ACT_GE_* | 2 | 通用数据存储 |
2. 可视化流程设计实战
2.1 创建第一个BPMN流程图
在resources目录下新建processes文件夹,右键选择New → Flowable BPMN File,命名为leave_process.bpmn20.xml。这个特殊的后缀告诉Flowable这是一个可执行的流程定义文件。
插件提供了完整的BPMN2.0元素面板:
- 事件:开始/结束/中间事件
- 任务:用户任务/服务任务/脚本任务
- 网关:排他/并行/包容网关
- 泳道:跨部门流程协作
2.2 构建请假审批流程图
让我们设计一个完整的请假审批流程:
- 开始事件:绿色圆形节点,触发流程启动
- 用户任务(员工提交):设置assignee为#{employee}
- 排他网关:判断请假天数是否超过3天
- 用户任务(主管审批):条件分支1(≤3天)
- 用户任务(经理审批):条件分支2(>3天)
- 服务任务(通知结果):无论通过与否都执行
- 结束事件:红色圆形节点,流程终止
连线条件配置示例:
<sequenceFlow id="flow1" sourceRef="gateway1" targetRef="managerTask"> <conditionExpression xsi:type="tFormalExpression"> <![CDATA[${days > 3}]]> </conditionExpression> </sequenceFlow>2.3 流程调试技巧
右键BPMN文件选择"View BPMN Diagram"可实时预览流程图。调试时常见问题解决:
- XML验证错误:检查所有节点必须有出口连线
- 变量未定义:确保表达式中的变量在运行时存在
- 任务分配异常:assignee表达式需返回有效用户ID
注意:修改流程定义后需要重新部署才能生效
3. Spring Boot集成深度解析
3.1 核心服务注入
Flowable通过Spring Boot自动配置了七个关键服务:
@Autowired private RepositoryService repositoryService; // 流程部署管理 @Autowired private RuntimeService runtimeService; // 流程实例控制 @Autowired private TaskService taskService; // 任务操作 @Autowired private HistoryService historyService; // 历史数据查询 @Autowired private ManagementService managementService; // 引擎管理 @Autowired private IdentityService identityService; // 用户权限 @Autowired private FormService formService; // 表单处理3.2 流程实例API实战
启动一个新流程实例的典型代码:
public String startLeaveProcess(String employee, int days, String reason) { Map<String, Object> variables = new HashMap<>(); variables.put("employee", employee); variables.put("days", days); variables.put("reason", reason); ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leave_process", variables ); return instance.getId(); }查询待办任务的RESTful接口示例:
@GetMapping("/tasks") public List<TaskDTO> getPendingTasks(@RequestParam String assignee) { return taskService.createTaskQuery() .taskAssignee(assignee) .list() .stream() .map(task -> new TaskDTO( task.getId(), task.getName(), runtimeService.getVariable(task.getExecutionId(), "reason") )) .collect(Collectors.toList()); }3.3 动态流程图渲染
实时显示流程进度的关键技术:
@GetMapping("/processDiagram") public void generateDiagram(HttpServletResponse response, @RequestParam String processId) throws IOException { ProcessInstance pi = runtimeService.createProcessInstanceQuery() .processInstanceId(processId) .singleResult(); BpmnModel model = repositoryService.getBpmnModel(pi.getProcessDefinitionId()); ProcessDiagramGenerator generator = ProcessEngineConfiguration .createStandaloneProcessEngineConfiguration() .getProcessDiagramGenerator(); try (InputStream is = generator.generateDiagram(model, "png", runtimeService.getActiveActivityIds(processId), Collections.emptyList(), "宋体", "宋体", "宋体", null, 1.0, false); OutputStream os = response.getOutputStream()) { IOUtils.copy(is, os); } }4. 生产级优化方案
4.1 性能调优配置
在application.yml中添加Flowable专属配置:
flowable: async-executor-activate: true # 启用异步执行器 database-schema-update: true # 自动更新数据库 history-level: audit # 适当的历史级别 mail-server-port: 1025 # 测试用邮件端口 process-definition-location-prefix: classpath:/processes/4.2 事务边界处理
Flowable操作必须放在事务中,推荐使用Spring的@Transactional:
@Transactional public void approveLeave(String taskId, boolean approved, String comment) { Task task = taskService.createTaskQuery() .taskId(taskId) .singleResult(); if (task == null) { throw new RuntimeException("任务不存在"); } Map<String, Object> vars = new HashMap<>(); vars.put("approved", approved); taskService.addComment(taskId, task.getProcessInstanceId(), comment); taskService.complete(taskId, vars); }4.3 异常处理策略
自定义异常处理器应对流程异常:
@ControllerAdvice public class FlowableExceptionHandler { @ExceptionHandler(FlowableException.class) public ResponseEntity<ErrorResponse> handleFlowableError(FlowableException ex) { ErrorResponse error = new ErrorResponse(); error.setTimestamp(LocalDateTime.now()); error.setMessage(ex.getMessage()); if (ex instanceof FlowableObjectNotFoundException) { error.setCode("PROCESS_NOT_FOUND"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error); } error.setCode("PROCESS_ERROR"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); } }5. 扩展应用场景
5.1 多级审批配置
对于复杂的审批链,可以使用callActivity实现流程嵌套:
<callActivity id="departmentApprove" name="部门审批" calledElement="deptApprovalProcess"> <extensionElements> <flowable:in source="applicant" target="deptApplicant"/> <flowable:out source="deptResult" target="deptApproved"/> </extensionElements> </callActivity>5.2 会签模式实现
多人并行审批的配置方法:
<userTask id="multiApprove" name="会签审批" flowable:assignee="${approvers}"> <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="${approverList}" flowable:elementVariable="approver"> <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6}</completionCondition> </multiInstanceLoopCharacteristics> </userTask>5.3 定时边界事件
实现审批超时自动处理:
<boundaryEvent id="timeoutEvent" attachedToRef="managerTask"> <timerEventDefinition> <timeDuration>PT24H</timeDuration> </timerEventDefinition> </boundaryEvent>配套的JavaDelegate实现:
public class TimeoutHandler implements JavaDelegate { @Override public void execute(DelegateExecution execution) { taskService.createComment( execution.getCurrentActivityId(), execution.getProcessInstanceId(), "审批超时自动通过" ); execution.setVariable("approved", true); } }在实际项目中,我们发现将流程图版本控制与业务代码同步管理能大幅减少部署问题。建议把BPMN文件也纳入Git仓库,每次流程修改都通过CI/CD管道自动部署到测试环境。
