准备环境

  • JDK8
  • IDEA
  • activiti-bpmn-visualizer 插件
  • MySQL8

依赖

添加activiti相关依赖

  1. <!--engine-->
  2. <dependency>
  3. <groupId>org.activiti</groupId>
  4. <artifactId>activiti-engine</artifactId>
  5. <version>7.1.0.M6</version>
  6. </dependency>
  7. <!--spring-->
  8. <dependency>
  9. <groupId>org.activiti</groupId>
  10. <artifactId>activiti-spring</artifactId>
  11. <version>7.1.0.M6</version>
  12. </dependency>
  13. <!--bpmn-model-->
  14. <dependency>
  15. <groupId>org.activiti</groupId>
  16. <artifactId>activiti-bpmn-model</artifactId>
  17. <version>7.1.0.M6</version>
  18. </dependency>
  19. <!--bpmn-convert-->
  20. <dependency>
  21. <groupId>org.activiti</groupId>
  22. <artifactId>activiti-bpmn-converter</artifactId>
  23. <version>7.1.0.M6</version>
  24. </dependency>
  25. <!-- activiti-json-converter -->
  26. <dependency>
  27. <groupId>org.activiti</groupId>
  28. <artifactId>activiti-json-converter</artifactId>
  29. <version>7.1.0.M6</version>
  30. </dependency>
  31. <!-- activiti-bpmn-layout -->
  32. <dependency>
  33. <groupId>org.activiti</groupId>
  34. <artifactId>activiti-bpmn-layout</artifactId>
  35. <version>7.1.0.M6</version>
  36. <scope>test</scope>
  37. </dependency>

其他依赖

<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.8</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

配置

在resource目录下新建bpmn文件夹和activiti.cfg.xml配置文件

activiti.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="druid" name="druid" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc://localhost:3306/activiti-demo?serverTimezone=GMT%2B8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="maxActive" value="5"/>
        <property name="maxWait" value="1"/>
    </bean>
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!--指定dataSource-->
        <property name="dataSource" ref="druid"/>
        <!--指定数据库表处理策略-->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  #1.flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常<br />      #2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建<br />      #3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)<br />      #4.drop-create: 在activiti启动时删除原来的旧表,然后创建新表(不需要手动关闭引擎)<br />      database-schema-update: true

建表

/**
     * 生成activiti 的数据库表
     */
    @Test
    void createTable() {
        //默认创建方式
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通用创建方式,指定文件名进行创建
        //ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml","processEngineConfiguration");
        //processEngineConfiguration.buildProcessEngine();
        System.out.println(processEngine);
    }

在自动生成activiti相关表的过程中会出现异常
【Table ‘activiti.act_ge_property’ doesn’t exist】
解决方法:
在配置的数据库连接url后面添加如下配置

 nullCatalogMeansCurrent=true
 即:
 <property name="url"
                  value="jdbc:mysql://localhost:3306/activiti-demo?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;nullCatalogMeansCurrent=true"/>

再次运行即可

数据库表

总共创建了25张关键的表:
actre: 流程定义相关
actru:流程运行相关,包括任务,变量
acthi:流程历史,历史信息
actge:通用的表,通用的属性配置

关键服务

activiti在使用过程中主要使用了五个服务类
image.png

RunTimeService

运行时服务

RepositoryService

对接数据来的service

HistoryService

流程运行历史service

TaskService

任务service

ManagementService

对流程引擎进行管理和维护

案例实现

package com.example.activitidemo.service;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * act流程业务
 *
 * @author xupu
 * @date 2021/10/24 20:58:19
 */
public class ActService {


    /**
     * 部署流程 文件上传方式
     */
    private void deployments() {
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3、进行部署
        Deployment deployment = repositoryService.createDeployment()
                                                 .addClasspathResource("bpmn/Leave.bpmn")
                                                 .addClasspathResource("bpmn/Leave.png")
                                                 .name("请假流程").deploy();
        //4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署Name:" + deployment.getName());
    }

    /**
     * 部署流程 zip压缩文件上传方式
     */
    private void deploymentsByZip() {
        //1、定义zip输入流
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("bpmn/Leave.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);

        //2、获取RepositoryService实例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3、进行部署
        Deployment deployment = repositoryService.createDeployment()
                                                 .addZipInputStream(zipInputStream)
                                                 .deploy();
        //4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署Name:" + deployment.getName());
    }

    /**
     * 启动流程实例
     */
    private void task() {
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //3、进行启动实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myLeave");
        //4、输出实例内容
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动id:" + processInstance.getActivityId());
    }

    /**
     * 查询当前个人待执行任务
     */
    private void findPersonalTaskList() {
        //1、当前任务负责人
        String assignee = "worker";
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3、根据流程key和任务负责人进行查询任务
        List<Task> list = taskService.createTaskQuery()
                                     .processDefinitionKey("myLeave")
                                     .taskAssignee(assignee)
                                     .list();
        for(Task task : list) {
            System.out.println("流程实例id:" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人任务id:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
        }
    }

    /**
     * 完成任务
     */
    private void completeTask() {
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取TaskService
        TaskService taskService = processEngine.getTaskService();
        //3、根据流程key 任务负责人查询对象
        //返回一个任务对象
        Task task = taskService.createTaskQuery().processDefinitionKey("myLeave").taskAssignee("worker").singleResult();

        //完成任务,完成之后会进入下一环节
        taskService.complete(task.getId());
    }

    /**
     * 查询已经定义的流程
     */
    private void findProcessDefinition() {
        //定义流程key
        String processKey = "myLeave";
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
                                                   .processDefinitionKey(processKey)
                                                   .list();
        //输出想看的参数信息
    }

    /**
     * 删除流程定义
     */

    private void deleteDefinition() {
        //流程部署id
        String processId = "1";
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取RuntimeService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //删除流程定义,但是如果该流程中还有流程实例处于启动中状态则删除错误
        repositoryService.deleteDeployment(processId);
        //设置true参数,会进行级联删除,即使存在启动中状态的实例也会删除,设置为false为非级联删除
        //也会将所有的历史记录进行删除
        //repositoryService.deleteDeployment(processId,true);

    }

    /**
     * 查询历史信息
     */
    private void findHistory() {
        //1、创建DefaultProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2、获取HistoryService
        HistoryService historyService = processEngine.getHistoryService();
        //获取actinst表的查询对象
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
        //有多种查询方法
        instanceQuery.processInstanceId("2501");
        instanceQuery.activityInstanceId("");
    }

}