Backend Development 24 min read

Activiti Workflow Engine: Design, Deployment, and Implementation of a Multi‑Level Approval Process

This article explains how to use the Activiti workflow engine to design a multi‑level leave‑approval process, covering BPMN diagram creation, Spring Boot configuration, deployment, Java code for starting instances, task handling, database schema, API overview, and tips for extending the workflow without additional code.

Architecture Digest
Architecture Digest
Architecture Digest
Activiti Workflow Engine: Design, Deployment, and Implementation of a Multi‑Level Approval Process

Introduction

The Activiti workflow engine simplifies the implementation of complex approval processes in office OA systems by handling task routing, branching, and state persistence, allowing developers to focus on front‑end forms and minimal back‑end code.

Designing the Approval Process

1. Draw a BPMN diagram that models the leave request, first‑level supervisor approval, optional second‑level approval for requests longer than three days, and final outcomes.

2. Use the Idea actiBPM plugin to create the diagram and export it as an XML file (e.g., apply.bpmn ).

Key BPMN Elements

User tasks for the applicant, first‑level supervisor, and second‑level supervisor.

Exclusive gateways to decide approval results and whether a second‑level review is needed (conditions like #{result1==true} and #{day>3} ).

Spring Boot Setup

Add the Activiti starter dependency:

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

Configure a data source (H2 for learning) and the process engine:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;mode=MySQL;"/>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <property name="dataSource" ref="dataSource"/>
    <property name="databaseSchemaUpdate" value="true"/>
</bean>

Core Java Code

Creating the engine and deploying the process:

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

Starting a process instance with variables:

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

Handling tasks (applicant, first‑level, second‑level):

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

// First‑level supervisor approves
Task secondTask = taskService.createTaskQuery().taskAssignee("li4").singleResult();
taskService.setVariable(secondTask.getId(), "result1", true);
taskService.complete(secondTask.getId());

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

Querying historic activity instances to view the full execution trace:

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());
}

Database Schema

Activiti creates several table groups:

ACT_RE_* – process definitions and resources.

ACT_RU_* – runtime data such as tasks, process instances, and variables.

ACT_HI_* – historic data for audit and reporting.

ACT_ID_* – identity and permission tables.

Additional tables for events, jobs, and timers.

API Overview

The five main services are:

ProcessEngine – entry point to obtain other services.

RepositoryService – deploy and manage process definitions.

RuntimeService – start, suspend, or delete process instances.

TaskService – query, claim, and complete user tasks.

HistoryService – retrieve completed tasks and historic process data.

BPMN Basics

BPMN (Business Process Model and Notation) is the standard for modeling business workflows. Activiti implements BPMN 2.0, allowing visual design of processes that are later executed by the engine.

Plugin Installation

Install the Idea actiBPM plugin from the provided URL to create and edit BPMN diagrams directly in the IDE.

Complete BPMN XML Example

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" ...>
    <process id="apply_processor_1" isExecutable="true">
        <startEvent id="_4" name="开始"/>
        <userTask id="_5" name="请假申请" activiti:assignee="#{applyUser}"/>
        <userTask id="_6" name="主管审批" activiti:assignee="${supervisor}"/>
        <exclusiveGateway id="_7" name="一级审批结果"/>
        ... (other elements and sequenceFlows with conditionExpression like #{result1==true})
    </process>
    ... (BPMNDiagram with shapes and edges)
</definitions>

Comparison with Similar Engines

Camunda and Flowable are popular alternatives built on the Activiti code base, offering similar modeling, deployment, and execution capabilities.

Further Learning Directions

Event types and listeners.

Different task types (service, script, user).

Form management and gateway configurations.

Performance tuning, ID generation, sharding.

Conclusion

Activiti is well‑suited for multi‑user business processes; creating a new workflow only requires redesigning the BPMN diagram and redeploying it, while front‑end pages and simple back‑end interfaces handle the rest.

javabackend developmentBPMNSpring BootActivitiWorkflow Engineprocess automation
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.