Designing and Implementing an OA Approval Workflow with Activiti: From BPMN Modeling to Spring Boot Integration
This article explains how to build a multi‑level office approval workflow using the Activiti engine, covering BPMN diagram design, deployment, Java code for process creation, task handling, gateway logic, database schema, API overview, framework comparisons, and further learning directions.
The workflow approval feature is a core capability of office OA systems, requiring careful design to handle multiple users, task transitions, and branch decisions.
Activiti Workflow Engine Overview
Activiti provides a powerful engine to model, deploy, and execute BPMN 2.0 processes, eliminating the need for custom code to drive flow control and branching.
Key Steps to Build a Workflow
Draw the BPMN diagram using the actiBPM plugin in IDEA.
Deploy the diagram to the engine.
Start a process instance with required variables.
Query and complete tasks for each approver.
Use exclusive gateways to decide branch paths based on variables such as ${day} or approval results.
Code Example: Deploying the Process
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("processes/apply.bpmn")
.deploy();This deployment creates the process definition in the ACT_RE_* tables.
Starting a Process Instance
Map
vars = new HashMap<>();
vars.put("applyUser", "zhang3");
vars.put("supervisor", "li4");
vars.put("upperSupervisor", "wang5");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("apply_processor_1", vars);The instance ID can be used later to query history.
Task Handling for Approvers
Task firstTask = taskService.createTaskQuery().taskAssignee("zhang3").singleResult();
taskService.complete(firstTask.getId(), Maps.newHashMap("day", 4));
Task secondTask = taskService.createTaskQuery().taskAssignee("li4").singleResult();
taskService.setVariable(secondTask.getId(), "result1", true);
taskService.complete(secondTask.getId());
Task thirdTask = taskService.createTaskQuery().taskAssignee("wang5").singleResult();
if (thirdTask != null) {
taskService.setVariable(thirdTask.getId(), "result2", true);
taskService.complete(thirdTask.getId());
}Variables set by each approver are evaluated by exclusive gateways to determine the next path.
Database Tables Used by Activiti
ACT_RE_* : Process definitions and resources.
ACT_RU_* : Runtime data such as tasks and executions.
ACT_HI_* : Historical activity records.
ACT_ID_* : Identity and permission data.
API Overview
ProcessEngine : Entry point to obtain services.
RepositoryService : Deploy and manage process definitions.
RuntimeService : Start and control process instances.
TaskService : Query, claim, and complete user tasks.
HistoryService : Retrieve historic activity and variable data.
Comparison with Camunda and Flowable
Both Camunda and Flowable are forks of Activiti and share a similar development workflow, but differ in community support, feature sets, and performance optimizations.
Further Learning Directions
Event types and listeners.
Different task types: user, service, script.
Form management and UI integration.
Parallel gateways and complex routing.
Scalability concerns: ID generation, sharding.
Conclusion
Activiti simplifies multi‑user approval processes by handling flow control and branching through BPMN models, requiring only minimal Java code for deployment, instance creation, and task completion, while front‑end pages handle user interaction.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.