SpringBoot整合activiti7工作流

环境准备

JDK1.6或者更高版本
数据库: mysql8 (也可选h2,oracle, postgres, mssql, db2等)

一、安装流程设计器

1 打开File->Settings->Plugins,在右侧搜索框搜索Activiti BPMN visualizer。


image.png

重启IDEA,就可以创建bpmn文件

image.png

二、activiti配置

在pom文件中引入activiti7坐标,版本号为:7.0.0.Beta2,pom全文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.panghu.project</groupId>
    <artifactId>activiti-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>7.0.0.Beta2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

添加application.yml配置:数据库信息对应成自己的即可

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/activiti?characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
  devtools:
    restart:
      enabled: true  #设置开启热部署
  activiti:
    database-schema-update: true
    history-level: full
    db-history-used: true

debug: true

启动springboot,看控制台以及对应的数据库生成了对应的25张表


image.png

act_re_:’re’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
act_ru_
:’ru’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
act_id_:’id’表示identity。这些表包含标识的信息,如用户,用户组,等等。
act_hi_
:’hi’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
act_ge_*:普通数据,各种情况都使用的数据。

1、act_ge_property:属性数据表。存储这个流程引擎级别的数据。
2、act_ge_bytearray:用来保存部署文件的大文本数据
3、act_re_deployment:用来存储部署时需要持久化保存下来的信息
4、act_re_procdef:业务流程定义数据表

注:此表和act_re_deployment是多对一的关系,即,一个部署的bar包里可能包含多个流程定义文件,每个流程定义文件都会有一条记录在act_reprocdef表内,每个流程定义的数据,都会对于act_ge_bytearray表内的一个资源文件和png图片文件。和act_ge_bytearray的关联是通过程序用act_ge_bytearray.name与act_re_procdef.name_完成的,在数据库表结构中没有体现。

5、act_ru_execution:流程执行记录。
6、act_ru_task:运行时任务数据表。
7、act_ru_identitylink:任务参与者数据表。主要存储当前节点参与者的信息。
8、act_ru_variable:运行时流程变量数据表。
9、act_hi_procinst:
10、act_hi_actinst:
11、act_hi_taskinst:
12、act_hi_detail:启动流程或者在任务complete之后,记录历史流程变量
13、act_hi_comment 意见表

流程文件部署主要涉及到3个表,分别是:act_ge_bytearray、act_re_deployment、act_re_procdef。主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的。

三、使用

先自定义创建一个流程


image.png

流程文件部署方式分为两种:自动部署和手动部署,将bpmn文件放到resources下的processes下,springboot启动时会自动部署,手动方式部署;在maven项目的测试文件夹下,新建测试类,并编写测试方法,进行流程文件部署,部署代码如下:

 /**
     * 涉及到的表
     *     act_ge_bytearray
     *         1、说明
     *             该表存储了bpmn文件和png图片
     *             从字段可以看出,根据deploymentID可以查询bpmn文件和png图片
     *         2、字段
     *             name_:存储该文件的路径名称
     *             deploymentid_id_:部署表的ID
     *             byte_:存放值(bpmn和png)
     *     act_re_deployment
     *         1、说明
     *             该表存储了部署的动作
     *         2、字段
     *            ID_:部署ID 主键
     *     act_re_procdef
     *         1、说明
     *             流程定义表
     *         2、字段
     *                id: 是由${name}:${version}:随机数   确定唯一的流程
     *             name_: 流程定义名称
     *             key_:  流程定义名称
     *             version_:  某一个流程定义的版本
     *             deployment_id_:部署表的ID
     *             
     *  说明:
     *      1、根据deploymentID-->查询图片和bpmn文件
     *      2、根据deploymentID-->查询流程定义
     *      3、只要流程名称不变,部署一次,版本号加1,id就发生变化,生成了一个新的deploymentID
     *      4、所以deploymentID和pdid是一一对应的关系
     */
     @Test
    public void testDeployment(){
        Deployment  deployment = repositoryService.createDeployment().name("测试流程文件部署")
        .addClasspathResource("test.bpmn")
        .addClasspathResource("test.png").deploy();
        
        log.info("部署id为:"+deployment.getId());
        log.info("部署名称为:"+deployment.getName());
    }

    //获取部署的流程
    @Test
    public void getDeployment() {
        List<Deployment> deploymentList = repositoryService.createDeploymentQuery().list();

        if (!CollectionUtils.isEmpty(deploymentList)) {
            deploymentList.stream().forEach(item -> {
                log.info("部署id为:" + item.getId());
                log.info("部署名称为:" + item.getName());
            });
        }
    }

启动流程:根据流程定义的key启动流程

    /**
     * 启动流程实例
     *    涉及到的表
     *       act_hi_actinst   hi:history   actinst:action instance
     *          1、概念
     *               所有的正在执行的或者已经完成的节点
     *          2、字段
     *              act_type_:为节点的类型
     *              end_time_: 如果有值,说明该节点已经结束了
     *       act_hi_procinst   procinst:process instance
     *          1、概念
     *               所有的正在执行的或者已经完成的流程实例
     *          2、字段
     *               end_time_:如果该字段有值,说明这个流程实例已经结束了
     *               end_act_id_:说明该流程实例是在哪个节点结束的
     *       act_hi_taskinst   taskinst:task instance
     *          1、概念
     *              所有的正在执行的或者已经完成的任务节点
     *          2、字段
     *              end_time_:如果该字段有值,说明任务已经完成了
     *              delete_reason:如果该值为completed,说明该任务处于完成的状态
     *       act_ru_execution  ru:runtime   
     *          1、概念
     *              代表正在执行的流程实例 
     *          2、字段
     *              id_:主键  executionid
     *              proc_inst_id_:  process instanceid
     *              proc_def_id_:pdid
     *              act_id_:当前的流程实例正在执行的节点的ID的值
     *       act_ru_task
     *          1、概念
     *              代表正在执行的任务
     *          2、字段
     *             id_:主键   任务ID
     *             execution_id_:piid,executionid
     *             name_:任务名称
     *          3、说明
     *               该表是一个临时表,该表中的任务完成以后,这一行会被删除掉   
     *              
     */
    @Test
    public void testStartProcess(){
        String instanceKey = "test";
        log.info("开启流程...");
        Map<String, Object> map = new HashMap<String, Object>();
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(instanceKey, map);
        log.info("启动流程实例成功:{}", instance);
        log.info("流程实例ID:{}", instance.getId());
        log.info("流程定义ID:{}", instance.getProcessDefinitionId());
    }

    //根据指定的任务办理人查询任务并办理
    @Test
    public void testGetTaskByAssignee(){
        List<Task> tasks = taskService.createTaskQuery().taskAssignee("张三").list();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("fullMsg", "家中有事请假5天");
        for (Task task : tasks) {
            log.info("任务id为=="+task.getId());
            taskService.complete(task.getId(),map);
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容