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);
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容