Designing and Implementing a Workflow Approval System with Activiti
This article explains how to design, configure, and code a multi‑level leave‑approval workflow using the Activiti BPM engine, covering process diagram creation, deployment, task handling, exclusive gateways, and database schema while providing complete Java examples and best‑practice recommendations.
Workflow approval is a core capability of office OA systems; designing such a system requires careful handling of multiple users, task routing, and branch conditions. Without a powerful workflow engine, extending or adding new processes becomes cumbersome.
Using the open‑source Activiti engine simplifies these challenges: adding a new process only requires drawing a BPMN diagram and integrating a front‑end page.
Basic Steps
Draw a process diagram.
Test the diagram.
Configure the Activiti project.
Design the workflow engine database.
Introduce the workflow engine APIs.
Understand BPMN diagrams.
Compare similar workflow engines.
Explore further learning directions.
Summarize.
To implement a leave‑approval system, first create a BPMN diagram (e.g., apply.bpmn ) that defines a two‑level supervisor approval flow.
Deploying the Process Diagram
// Create the process engine
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// RepositoryService for deployment
RepositoryService repositoryService = engine.getRepositoryService();
// Deploy the leave‑process diagram
repositoryService.createDeployment().addClasspathResource("processes/apply.bpmn").deploy();The deployment typically runs in the backend; no code changes are needed after the diagram is uploaded.
Starting a New Process Instance
Map
variableMap = new HashMap<>();
variableMap.put("applyUser", "zhang3");
variableMap.put("supervisor", "li4");
variableMap.put("upperSupervisor", "wang5");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("apply_processor_1", variableMap);The variables set the applicant and the two supervisors. The process key apply_processor_1 is defined in the BPMN file.
Completing the Applicant's Task
TaskService taskService = engine.getTaskService();
Task firstTask = taskService.createTaskQuery().taskAssignee("zhang3").singleResult();
taskService.complete(firstTask.getId(), Maps.newHashMap("day", 4));This step records the leave days (e.g., 4 days) and moves the flow to the supervisor approval node.
First‑Level Supervisor Approval
Task secondTask = taskService.createTaskQuery().taskAssignee("li4").singleResult();
taskService.setVariable(secondTask.getId(), "result1", true);
taskService.complete(secondTask.getId());The variable result1 determines which exclusive‑gateway branch is taken.
Second‑Level Supervisor Approval (if needed)
Task thirdTask = taskService.createTaskQuery().taskAssignee("wang5").singleResult();
if (thirdTask != null) {
taskService.setVariable(thirdTask.getId(), "result2", true);
taskService.complete(thirdTask.getId());
} else {
// No second‑level approval required
}The exclusive gateway uses the condition #{day>3} to decide whether this step is executed.
Viewing the Execution History
List
activityInstanceList = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(instance.getId())
.list();
for (HistoricActivityInstance historicActivityInstance : activityInstanceList) {
log.warn("activityName:{}, activityType:{}, assignee:{}, taskId:{}",
historicActivityInstance.getActivityName(),
historicActivityInstance.getActivityType(),
historicActivityInstance.getAssignee(),
historicActivityInstance.getTaskId());
}This logs each executed node, allowing full traceability of the workflow.
Project Basic Configuration
Add the Activiti starter dependency:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.23.0</version>
</dependency>Use Spring Boot parent 2.5.4 and configure a datasource (H2 for learning or MySQL for production). Example XML configuration creates the datasource and the StandaloneProcessEngineConfiguration bean.
Database Schema
Activiti creates several tables:
ACT_RE_* – process definitions and resources.
ACT_RU_* – runtime data such as tasks, process instances, and variables.
ACT_HI_* – historic data for audit and analysis.
ACT_ID_* – user, group, and permission information.
Other auxiliary tables for events, jobs, and timers.
Workflow Engine API Overview
ProcessEngine : entry point to obtain service APIs.
RepositoryService : deploy and manage process definitions.
RuntimeService : start, suspend, or delete process instances.
TaskService : query, claim, and complete tasks.
HistoryService : query completed tasks and historic process data.
What is BPMN?
BPMN (Business Process Model and Notation) is a standard for modeling business processes. Activiti implements BPMN 2.0, allowing designers to create XML‑based process definitions that the engine can execute.
Further Learning Directions
Event types and listeners.
Different task types (user, service, script).
Form management.
Parallel and exclusive gateways.
Performance, scaling, and sharding strategies.
Summary
Activiti is suitable for multi‑user process management.
Workflow development consists of diagram design, deployment, and instance execution.
Adding new process templates requires no additional code; only front‑end pages and simple back‑end interfaces need to be adapted.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
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.