Deep Dive into Flowable: Core Concepts, Architecture, and Spring Boot Integration
This article explains what a workflow engine is, outlines Flowable’s core architecture and BPMN support, and provides a step‑by‑step Spring Boot integration example—including Maven setup, BPMN model definition, and Java code for starting, submitting, and approving a leave request—while discussing version and archiving recommendations.
1. Overview
A workflow engine abstracts business processes and the rules that govern the sequence of tasks. The article begins by defining a workflow as a formalized, computer‑driven way to move documents, information, or tasks among participants according to predefined rules, using the example of a leave request (submit → manager approval → result → HR copy).
2. Flowable Core Concepts and Architecture
Flowable is an Apache‑2.0‑licensed open‑source BPM engine derived from Activiti. It implements the BPMN 2.0 specification and provides services for process definition, runtime control, task handling, history queries, and engine management.
The main services and typical methods are:
RepositoryService : deploy(), createDeployment() – manage process definitions and deployments.
RuntimeService : startProcessInstanceByKey() – control running process instances.
TaskService : complete(), claim() – operate on user tasks.
HistoryService : createHistoricTaskInstanceQuery() – query historical data.
ManagementService : executeCustomSql() – engine administration.
The central entry point is ProcessEngine, obtained via ProcessEngines.getDefaultProcessEngine(), which gives access to all the services.
3. Spring Boot Integration Demo
3.1 Dependency Configuration
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.2</version>
</dependency>3.2 Process Model Definition
A simple leave‑request BPMN file leave-process.bpmn20.xml is placed under src/main/resources/processes:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:flowable="http://flowable.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
targetNamespace="http://www.flowable.org/processdef">
<process id="leave-process" name="leave-process" isExecutable="true">
<startEvent id="sid-3cb4e010-243b-401b-9ad3-4a1f8ecf35d7"/>
<userTask id="sid-c60eebb9-3a5b-48f9-963c-d0b064344fad" name="请假" flowable:assignee="#{leaveTask}">
<documentation>员工请假</documentation>
</userTask>
<sequenceFlow id="sid-ff0c2afe-1c1c-4e2f-b2eb-5083c5fadb41" sourceRef="sid-3cb4e010-243b-401b-9ad3-4a1f8ecf35d7" targetRef="sid-c60eebb9-3a5b-48f9-963c-d0b064344fad"/>
<!-- additional tasks, gateways, and serviceTask omitted for brevity -->
</process>
</definitions>When the application starts, Flowable automatically loads this definition and creates the required database tables.
3.3 Using the Process Model
Java code to start a leave request and set process variables:
@Autowired
RuntimeService runtimeService;
@Autowired
TaskService taskService;
public static final String userId = "user_001";
public static final String teamId = "team_001";
public static final String depId = "dep_001";
@Test
public void leaveRequest() {
HashMap<String, Object> map = new HashMap<>();
map.put("leaveTask", userId);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-process", map);
runtimeService.setVariable(processInstance.getId(), "name", "java-boy");
runtimeService.setVariable(processInstance.getId(), "reason", "想休息个几天,心累了");
runtimeService.setVariable(processInstance.getId(), "days", 3);
log.info("======>>>创建请假流程, 流程实例processInstanceId:{}", processInstance.getId());
}Submitting the request to the team leader:
@Test
public void submitToTeam() {
List<Task> list = taskService.createTaskQuery().taskAssignee(userId).orderByTaskId().desc().list();
for (Task task : list) {
Map<String, Object> map = new HashMap<>();
map.put("teamTask", teamId);
taskService.complete(task.getId(), map);
}
}Team leader approval (passing the request to the manager):
@Test
public void teamApprove() {
List<Task> list = taskService.createTaskQuery().taskAssignee(teamId).orderByTaskId().desc().list();
for (Task task : list) {
Map<String, Object> map = new HashMap<>();
map.put("manageTask", depId);
map.put("checkResult", "通过");
map.put("teamTask", teamId);
try {
taskService.complete(task.getId(), map);
} catch (Exception e) {
log.error("组长审批失败{} {}", task.getId(), task.getAssignee(), e);
}
}
}Manager approval and final end events follow a similar pattern, using the same services to complete tasks and set variables.
4. Summary
Flowable balances rich functionality with ease of use. Although its database schema appears complex, proper configuration simplifies integration. For Java projects that need full BPM capabilities while remaining lightweight, Flowable remains a top choice, especially within the Spring ecosystem. New projects are advised to start with version 6.7.x and to plan a sensible historical data archiving strategy.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
