Backend Development 25 min read

Building a Multi‑Level Approval Workflow with Activiti in Java

This article demonstrates how to design, deploy, and run a two‑level leave‑approval workflow using the Activiti BPMN engine, covering diagram creation, Spring Boot configuration, process variables, task handling, exclusive gateways, database tables, API overview, and best‑practice tips for extending the flow.

Top Architect
Top Architect
Top Architect
Building a Multi‑Level Approval Workflow with Activiti in Java

The core of an office OA system is the workflow approval feature; designing a robust multi‑level approval process can be simplified with the Activiti open‑source workflow engine.

Step 1 – Draw the BPMN diagram : Use the actiBPM plugin in IntelliJ to create a diagram (apply.bpmn) that defines a first‑level supervisor approval and, if the leave exceeds three days, a second‑level supervisor approval.

Step 2 – Deploy the diagram :

ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
repositoryService.createDeployment()
    .addClasspathResource("processes/apply.bpmn")
    .deploy();

The deployment code is usually placed in the backend service; no further code changes are needed after the diagram is uploaded.

Step 3 – Start a process instance by providing the applicant and supervisors:

Map
variableMap = new HashMap<>();
variableMap.put("applyUser", "zhang3");
variableMap.put("supervisor", "li4");
variableMap.put("upperSupervisor", "wang5");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("apply_processor_1", variableMap);

Step 4 – Complete the applicant's task and set the requested leave days:

Task firstTask = taskService.createTaskQuery()
    .taskAssignee("zhang3")
    .singleResult();
taskService.complete(firstTask.getId(), Maps.newHashMap("day", 4));

Step 5 – First‑level supervisor approval (sets result1 variable):

Task secondTask = taskService.createTaskQuery()
    .taskAssignee("li4")
    .singleResult();
taskService.setVariable(secondTask.getId(), "result1", true);
taskService.complete(secondTask.getId());

Step 6 – Conditional second‑level approval (executed only when day > 3 ):

Task thirdTask = taskService.createTaskQuery()
    .taskAssignee("wang5")
    .singleResult();
if (thirdTask != null) {
    taskService.setVariable(thirdTask.getId(), "result2", true);
    taskService.complete(thirdTask.getId());
}

The exclusive gateways in the BPMN file use expressions such as #{result1==true} and #{day>3} to decide which path to follow, eliminating the need for custom branching code.

Database tables created by Activiti :

Definition tables: ACT_RE_*

Runtime tables: ACT_RU_*

History tables: ACT_HI_*

Identity tables: ACT_ID_*

Key services (API) :

ProcessEngine – entry point to obtain other services.

RepositoryService – deploy and delete process definitions.

RuntimeService – start, suspend, or delete process instances.

TaskService – query, claim, and complete tasks.

HistoryService – query completed tasks and historic variables.

Project setup (Spring Boot 2.5.4, Activiti 5.23.0):

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter-basic</artifactId>
    <version>5.23.0</version>
</dependency>

Configure a datasource (H2 for quick testing) and the engine configuration bean as shown in the original XML snippet.

Extending the flow : To add HR approval for sick leave, insert an exclusive gateway before the final approval node and create a new user task with assignee ${hr} , using the same pattern of variables and gateways—no additional Java code is required.

Comparison with other BPM engines (Camunda, Flowable) shows similar five‑step usage: design BPMN, deploy, start instance, execute tasks, and monitor.

Learning roadmap includes event listeners, task types, form management, parallel gateways, performance tuning, and database sharding.

Summary : Activiti enables multi‑user workflow management with minimal code; the heavy lifting of task routing and state persistence is handled by the engine, leaving developers to focus on UI and simple service interfaces.

JavaworkflowBPMNSpringBootActiviti
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.