Backend Development 29 min read

Using Activiti7 with SpringBoot: Dependency Setup, Deployment, Process Execution, and Advanced Operations

This article provides a step‑by‑step guide on integrating Activiti7 into a SpringBoot project, covering Maven dependencies, IDE configuration, deployment of BPMN files, starting and managing process instances, handling tasks, business keys, process variables, candidate users, and gateway configurations, all illustrated with complete Java code examples.

Top Architect
Top Architect
Top Architect
Using Activiti7 with SpringBoot: Dependency Setup, Deployment, Process Execution, and Advanced Operations

The article introduces how to use Activiti7 in a SpringBoot project, starting with the required Maven dependencies and explaining how to exclude conflicting libraries.

Dependencies

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.0.0.SR1</version>
    <exclusions>
        <exclusion>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-image-generator</artifactId>
    <version>7.0.0.SR1</version>
</dependency>

Activiti environment installation

// IDEA settings to use UTF‑8
File → Settings → Editor → File Encodings → UTF‑8
// VM options
Help → Edit Custom VM Options → add "-Dfile.encoding=UTF-8"
// Modify idea.exe.vmoptions and idea64.exe.vmoptions to include "-Dfile.encoding=UTF-8" and restart IDEA

Basic operations

1. Deploy the process definition

@Test
public void testDeploy() {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("bpmn/leave.bpmn")
        .name("请假流程")
        .deploy();
    System.out.println("流程部署ID:" + deployment.getId());
    System.out.println("流程部署名称:" + deployment.getName());
}

2. Start a process instance

@Test
public void testStartProcess() {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess");
    System.out.println("流程定义的id = " + instance.getProcessDefinitionId());
    System.out.println("流程实例的id = " + instance.getId());
}

3. Query pending tasks

@Test
public void testSelectTodoTaskList() {
    String assignee = "李四";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    List
taskList = taskService.createTaskQuery()
        .processDefinitionKey("leaveProcess")
        .taskAssignee(assignee)
        .list();
    for (Task task : taskList) {
        System.out.println("流程定义id = " + task.getProcessDefinitionId());
        System.out.println("流程实例id = " + task.getProcessInstanceId());
        System.out.println("任务id = " + task.getId());
        System.out.println("任务名称 = " + task.getName());
    }
}

4. Complete a task

@Test
public void testCompleteTask() {
    String assignee = "李四";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    List
taskList = taskService.createTaskQuery()
        .processDefinitionKey("leaveProcess")
        .taskAssignee(assignee)
        .list();
    for (Task task : taskList) {
        taskService.complete(task.getId());
    }
}

5. Add a comment to a task

@Test
public void testAddComment() {
    String assignee = "王五";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    List
taskList = taskService.createTaskQuery()
        .processDefinitionKey("leaveProcess")
        .taskAssignee(assignee)
        .list();
    for (Task task : taskList) {
        taskService.addComment(task.getId(), task.getProcessInstanceId(), task.getName() + "审批通过");
        taskService.complete(task.getId());
    }
}

Advanced operations

Process definition query, resource download, and deletion

@Test
public void testDefinitionQuery() {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    List
list = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("leaveProcess")
        .list();
    for (ProcessDefinition def : list) {
        System.out.println("流程定义ID:" + def.getId());
        System.out.println("流程定义名称:" + def.getName());
        System.out.println("流程定义key:" + def.getKey());
        System.out.println("流程定义版本:" + def.getVersion());
        System.out.println("流程部署ID:" + def.getDeploymentId());
        System.out.println("====================");
    }
}
@Test
public void testDownloadResource() throws Exception {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    List
list = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("leaveProcess")
        .orderByProcessDefinitionVersion().desc()
        .list();
    ProcessDefinition definition = list.get(0);
    String deploymentId = definition.getDeploymentId();
    InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, definition.getResourceName());
    InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, definition.getDiagramResourceName());
    FileOutputStream bpmnOut = new FileOutputStream("D:/leave.bpmn");
    FileOutputStream pngOut = new FileOutputStream("D:/leave.png");
    IOUtils.copy(bpmnInput, bpmnOut);
    IOUtils.copy(pngInput, pngOut);
}
@Test
public void testDeleteDeploy() {
    String deploymentId = "10001";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    repositoryService.deleteDeployment(deploymentId);
    // repositoryService.deleteDeployment(deploymentId, true); // cascade delete
}

BusinessKey usage

@Test
public void testStartProcessWithBusinessKey() {
    String businessKey = "8001";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess", businessKey);
    System.out.println("业务key:" + instance.getBusinessKey());
}

Suspending and activating process definitions and instances

@Test
public void testSuspendAllProcessInstance() {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("leaveProcess")
        .singleResult();
    boolean suspended = pd.isSuspended();
    String id = pd.getId();
    if (suspended) {
        repositoryService.activateProcessDefinitionById(id, true, null);
    } else {
        repositoryService.suspendProcessDefinitionById(id, true, null);
    }
}
@Test
public void testSuspendSingleProcessInstance() {
    String processInstanceId = "2501";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance pi = runtimeService.createProcessInstanceQuery()
        .processInstanceId(processInstanceId)
        .singleResult();
    if (pi.isSuspended()) {
        runtimeService.activateProcessInstanceById(processInstanceId);
    } else {
        runtimeService.suspendProcessInstanceById(processInstanceId);
    }
}

Candidate users and task claiming

@Test
public void testSelectCandidateTaskList() {
    String candidateUser = "李四";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    List
taskList = taskService.createTaskQuery()
        .processDefinitionKey("leaveCandidateProcess")
        .taskCandidateUser(candidateUser)
        .list();
    for (Task task : taskList) {
        System.out.println("任务id = " + task.getId());
    }
}
@Test
public void testClaimTask() {
    String taskId = "2505";
    String assignee = "张三";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    taskService.claim(taskId, assignee);
}

Gateway examples (exclusive, parallel, inclusive) with corresponding Java test classes are also provided, showing how to set process variables and let the engine route the flow based on conditions.

Finally, the article lists a summary of common Activiti services (RepositoryService, RuntimeService, TaskService, HistoryService, ManagementService) and common commands for deployment, starting processes, querying tasks, completing tasks, adding comments, suspending/activating definitions and instances, downloading resources, and deleting deployments.

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