Backend Development 21 min read

Integrating Flowable Workflow Engine with Spring Boot: A Comprehensive Guide

This article provides a step‑by‑step tutorial on integrating the Flowable BPMN workflow engine into a Spring Boot application, covering dependencies, BPMN diagram creation, task configuration, service implementation, process visualization, and common pitfalls such as font issues and process definition updates.

Top Architect
Top Architect
Top Architect
Integrating Flowable Workflow Engine with Spring Boot: A Comprehensive Guide

1. Workflow Overview

The early workflow engine jBPM, created by Tom Baeyens, split into Activiti, Flowable, and Camunda. Each engine has distinct characteristics: Activiti leans toward Spring Cloud and Docker, Flowable offers rich extensions, and Camunda provides a lightweight BPMN editor.

2. Related Concepts

A typical BPMN diagram consists of events, sequence flows, tasks, and gateways. Events include start, end, and intermediate types. Sequence flows connect elements, optionally with conditions. Tasks can be user, service, script, or receive tasks. Gateways control flow branching, such as exclusive, parallel, event, and inclusive gateways.

3. Spring Boot Integration of Flowable

3.1 Create Spring Boot project and add dependencies

Use your IDE to create a Spring Boot project. Add MySQL and MyBatis dependencies because Flowable requires a database.

<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>6.7.2</version>
</dependency>

By default, any BPMN files placed under resources/processes are automatically deployed.

3.2 Draw the process diagram

Use Flowable UI visualizer or an IDE plugin to design the BPMN file (e.g., ask_for_leave.bpmn20.xml ). The diagram includes start event → employee user task → team‑lead approval → manager approval, with exclusive gateways handling approval/rejection paths.

3.3 Service task implementation

@Slf4j
@Component
public class LeaveFailService implements JavaDelegate {
    @Override
    public void execute(DelegateExecution delegateExecution) {
        log.info("审批不通过{}", delegateExecution.getCurrentActivityId());
    }
}

The class implements JavaDelegate and is invoked automatically when the service task runs.

3.4 Process diagram viewing API

/**
 * LeaveController
 * @Description:
 * @Author: wangyubiao
 * @Date 2023/5/12 13:26
 */
@RestController
public class LeaveController {
    @Autowired RuntimeService runtimeService;
    @Autowired RepositoryService repositoryService;
    @Autowired ProcessEngine processEngine;

    @GetMapping("/pic")
    public void showPic(HttpServletResponse resp, String processId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processId).singleResult();
        if (pi == null) { return; }
        List
executions = runtimeService.createExecutionQuery()
                .processInstanceId(processId).list();
        List
activityIds = new ArrayList<>();
        List
flows = new ArrayList<>();
        for (Execution exe : executions) {
            activityIds.addAll(runtimeService.getActiveActivityIds(exe.getId()));
        }
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows,
                engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(),
                engconf.getClassLoader(), 1.0, false);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int length = 0;
        try {
            out = resp.getOutputStream();
            while ((length = in.read(buf)) != -1) {
                out.write(buf, 0, length);
            }
        } finally {
            if (in != null) in.close();
            if (out != null) out.close();
        }
    }
}

The endpoint returns a PNG image showing the current state of the process instance.

3.5 Unit tests

import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
@Slf4j
@ActiveProfiles("dev")
class ProcessApplicationTests {
    @Autowired RuntimeService runtimeService;
    @Autowired TaskService taskService;
    public static final String yuangongId = "yuangongID_3";
    public static final String zuzhangId = "zuzhangId_3";
    public static final String manageId = "manageId_3";

    @Test void contextLoads() {}

    /*** start leave process ***/
    @Test void askForLeave() {
        HashMap
map = new HashMap<>();
        map.put("leaveTask", yuangongId);
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("ask_for_leave", map);
        runtimeService.setVariable(pi.getId(), "name", "javaboy");
        runtimeService.setVariable(pi.getId(), "reason", "休息一下");
        runtimeService.setVariable(pi.getId(), "days", 10);
        log.info("创建请假流程 processId:{}", pi.getId());
    }
    // ... other test methods for submitting, approving, rejecting ...
}

The tests demonstrate how to start the process, complete user tasks, and handle approval decisions.

4. Common Issues

4.1 Diagram text appears as garbled characters

This occurs when the server lacks a default font. Configure Flowable to use a font like "宋体" via a custom EngineConfigurationConfigurer implementation.

4.2 Modifying a BPMN file does not affect already running instances

Running process instances use the definition snapshot stored at start‑time; changes only affect new instances.

Overall, the guide walks readers through setting up Flowable in Spring Boot, designing BPMN models, implementing service tasks, visualizing process state, testing, and troubleshooting typical problems.

JavaIntegrationworkflowBPMNSpringBootFlowable
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.