Activiti工作流

引言

工作流在实际管理系统中使用面非常广泛,是有深入学习的必要性的,基于这种背景,快速地整理和学习相关内容就会借鉴相关的博客、文档,原文链接附属如下:

原文链接:https://blog.csdn.net/aa5931/article/details/121007664

1 工作流

1.1 概念

通过计算机程序实现业务流程自动化管理,即实现对多个参与者之间按照预先定义的处理规则自动传递文档、信息、任务的过程管理

1.2 作用

1、提高系统的柔性,适应业务流程的变化

2、实现更好的业务过程控制,提高顾客服务质量

3、降低系统开发和维护成本

1.3应用

1.业务流程:订单、报价处理、申请和审批、客户电话处理、供应链管理等

2.行政管理:出差申请、加班申请、请假申请、用车申请、会议室申请等一切需要申请和审批的需要多人流转处理的流程

3.人事管理:员工培训安排、绩效考核、职位变动、员工档案管理、KPI计划

4.财务管理:付款请求、报销处理、售后服务、预算审批、出差报销、计划申请、贷后管理

5.客户服务:客户信息管理、客户投诉、请求处理、收获服务管理

6.其它服务:质量管理、产品管理、物流货物跟踪处理

1.4 行业例举

银行、证券、ERP、MES、SCM、WMS、物流、贸易、政务、OA等(只要业务需要多人流转协作完成,就能应用工作流)。

2 Activiti

2.1 介绍

Activiti 是一个轻量级、开源的工作流和业务流程管理(BPM)系统,基于 Java 开发。它使用了 BPMN 2.0 (Business Process Model and Notation) 建模语言,提供了流程设计、部署、执行和监控等功能。

开发手册:​​​​https://github.com/Activiti/activiti-7-developers-guide

官方地址:https://www.activiti.org/

2.2 功能特点

1 工作流引擎

ProcessEngine对象: 这是Activiti工作的核心.负责生成流程运行时的各种实例及数据,监控和管理流程的运行

2 BPM

BPM(业务流程管理):是一种以规范化地构造端到端的业务流程为中心,以持续的提高组织业务绩效为目的的系统化思想

3 BPMN

BPMN(Business Process Model and Notation)是实现BPM思想的一种方案 ,即定义了业务流程模型和流程使用符号的规则,定义的内容可以以.bpmn文件的方式导入导出,这种文件叫做流程定义文件。

BPMN也是一种XML文件格式,当然idea可以通过actiBPM插件实现对该文件的可视化以及拖拽流程符合自定义流程定义。

【注:】

要注意上述对规则的描述,实际上就是两个规则,一个是流程模型规则,一个是流程节点符号规则。

​​​​https://github.com/Activiti/activiti-7-developers-guide

4 BPD

BPMN是建模语言实现的一种规范,而BPD(Business Process Diagram)是图示,用来展示建模语言定义出来的流程,往往面向设计者和流程参与者。

5 流对象

流对象(process engine)通过它可以获得我们需要的一切activiti服务

一个业务流程图有三类流对象的核心元素

事件

一个事件用圆圈来描述,表示一个业务流程期间发生的东西。事件影响流程的流动,一般有一个原因(触发器)或一个影响(结果),基于它们对流程的影响,有三种事件:开始事件,中间事件,终止事件。

活动

用圆角矩形表示,一个流程由一个活动或多个活动组成

条件

条件用菱形表示,用于控制序列流的分支与合并,可以作为选择,包括路径的分支与合,内部的标记会给出控制流的类型

  • 排他网关(Exclusive Gateway):

    • 只选择一个路径;

    • 流程执行到该网关时候,按照输出流的顺序逐个计算,当条件的计算结果为true时继续执行当前网关的输出流;如果多条结果为true则会执行第一个值为true的线路;如果都没有true则抛出异常;

    • 排他网关需要和条件顺序流结合使用 ,default属性指定默认顺序流,当所有条件不满足时候会执行默认顺序流。

  • 并行网关(Parallel Gateway):

    • 同时执行所有路径;

      • 拆分:并行执行所有输出顺序流,为每一条顺序流创建一个并行执行线路;

      • 合并 :所有从并行网关拆分并执行完成的线路均在此等待,直到所有线路都执行完成才继续执行;

  • 包容网关(Inclusive Gateway):

    • 基于条件选择一条或多条路径;

      • 拆分:计算每条线路的表达式,当表达式结果为true,创建一个并行线路继续执行;

      • 合并:所有从并行网关拆分并执行完成的线路均在此等待,直到所有线路都执行完成才继续执行;

  • 事件网关(Event-based Gateway):

    • 基于事件选择路径;

    • 专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件。当流程执行到事件网关后,流程处于等待状态,需要等待抛出事件才能继续执行;

6 流向

流是连接两个流程节点的连线,常见以下几种:

2.3 使用步骤

1 部署activiti

引入activiti的maven依赖、下载jar包、通过源码build jar包

2 流程定义

使用activiti的流程定义工具,用流程符号把整个流程设计出来

3 流程定义部署

导入流程定义文件,使用activiti提供的api解析文件数据并存储到数据库

4 启动流程实例

启动一个流程实例表示开始一次业务流程的运行(processInstance)

5 用户查询待办任务(Task)

将系统的业务流程已经交给activiti管理,通过activiti就可以查询当前流程执行到哪里了,当前用户需要办理什么任务,activiti帮我们管理执行操作

6 用户已办任务历史记录

用户可以查询已经办理的业务和正在处理的任务,查询历史任务表获得具体流程执行细节,当一个流程没有下一节点时,整个流程实例就执行结束

7 流程跟踪

用户可以查看当前流程实例流传到了哪个岗哪个员工

2.4 Activiti系统服务结构图

核心类

ProcessEngine: 流程引擎的抽象,可以通过此类获取需要的所有服务;

服务类

XxxService

通过ProcessEngine获取,Activiti将不同生命周期的服务封装在不同Service中,包括定义,部署,运行.通过服务类可获取相关生命周期中的服务信息;

RepositoryService

Repository Service提供了对repository的存取服务,Activiti中每一个不同版本的业务流程的定义都需要使用一些定义文件,部署文件和支持数据(例如BPMN2.0XML文件,表单定义文件,流程定义图像文件等),这些文件都存储在Activiti内建的Repository中

RuntimeService

Runtime Service提供了启动流程,查询流程实例,设置获取流程实例变量等功能.此外它还提供了对流程部署,流程定义和流程实例的存取服务

TaskService

Task Service提供了对用户Task和Form相关的操作.它提供了运行时任务查询,领取,完成,删除以及变量设置等功能

HistoryService

History Service用于获取正在运行或已经完成的流程实例的信息,与Runtime Service获取的流程信息不同,历史信息包含已经持久化存储的永久信息,并已经被针对查询优化

FormService

使用Form Service可以存取启动和完成任务所需的表单数据并且根据需要来渲染表单

Activiti中的流程和状态Task均可以关联业务相关的数据

IdentityService

Identity Service提供了对Activiti系统中的用户和组的管理功,Activiti中内置了用户以及组管理的功能,必须使用这些用户和组的信息才能获取到相应的Task

ManagementService

Management Service提供了对Activiti流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用。主要用于 Activiti 系统的日常维护核心业务对象:org.activiti.engine.impl.persistence.entity包下的类,Task,ProcessInstance,Execution等根据不同职责实现相应接口的方法(如需要持久化则继承PersistentObject接口),与传统的实体类不同

(注:Activiti7删除了FormService和IdentityService接口),工作流程与业务解耦,结合具体业务自由的配置用户和用户组。

2.5 开发环境

JDK1.8及以上版本

Mysql5及以上版本

Tomcat8.5

IDEA

Activiti7.00 Beta1 默认支持Spring5

Activiti数据库表结构

Activiti7工作流总共包含25张数据表(Activiti6包含23张表),Activiti会自动帮你生成这25张表,所有的表名默认以"ACT_"开头

表具体功能介绍
bash 复制代码
表名	                介绍
act_evt_log	            流程引擎通用日志表
act_ge_bytearray	    二进制表,存储通用的流程资源
act_ge_property	        引擎配置信息表,通常在引擎初始化时自动生成,管理引擎运行和流程执行,默认存储三条数据
act_hi_actinst	        历史节点表
act_hi_attachment	    历史附件表
act_hi_comment	        历史意见表
act_hi_detail	        历史详情表
act_hi_identitylink	    历史用户信息表
act_hi_procinst	        历史流程实例表
act_hi_taskinst	        历史任务实例表
act_hi_varinst	        历史变量表
act_procdef_info	    流程定义的动态变更信息
act_re_deployment	    部署信息表
act_re_model	        流程设计实体表
act_re_procdef	        流程定义数据表
act_ru_deadletter_job	作业失败表,失败次数>重试次数
act_ru_event_subscr	    运行时事件表
act_ru_execution	    运行时流程执行实例表
act_ru_identitylink	    运行时用户信息表
act_ru_integration	    运行时综合表
act_ru_job	            作业表
act_ru_suspended_job	作业暂停表
act_ru_task	            运行时任务信息表
act_ru_timer_job	    运行时定时器表
act_ru_variable	        运行时变量表

【注:】根据表名前缀区分功能概述:

ACT_GE_ (GE) 表示 general 全局通用数据及设置,各种情况都使用的数据;

ACT_HI_ (HI) 表示 history 历史数据表,包含着程执行的历史相关数据,如结束的流程实例,变量,任务,等等;

ACT_RE_ (RE) 表示 repository 存储,包含的是静态信息,如,流程定义,流程的资源(图片,规则等);

ACT_RU_ (RU) 表示 runtime 运行时,运行时的流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti 只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快;

流程步骤

1 部署Activiti

Activiti是一个工作流引擎(其实就是一堆jar包API),业务系统访问(操作)activiti的接口,就可以方便的操作流程相关数据,这样就可以把工作流环境与业务系统的环境集成在一起,操作此处忽略。

2 流程定义

工作流要有流程模型图,使用activiti流程建模工具(activity-designer)定义业务流程(.bpmn文件) 绘制好流程模型,.bpmn文件就是业务流程定义文件,通过xml定义业务流程,具体如下:

设计一个evection.bpmn(出差申请流程),设计流程需要的节点(设置开始事件的id和name,设置活动的assignee)

3 部署流程

将画好的流程图(activiti部署业务流程定义(.bpmn文件)),使用activiti提供的api把流程定义内容存储起来,在Activiti执行过程中可以查询定义的内容,Activiti执行把流程定义内容存储在数据库中

流程部署:通过流程引擎启动部署

java 复制代码
    @Test
    public void deployTest(){
        // 从resources读取制指定文件的信息
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
                .name("出差申请流程")
                .addClasspathResource("bpmn/evection.bpmn")
                .addClasspathResource("bpmn/evection.png")
                .disableSchemaValidation() // 禁止架构验证
                .deploy();
        System.out.println("流程部署id="+deployment.getId());
        System.out.println("流程部署名字="+deployment.getName());


    }

此时以下表会自动生成数据

sql 复制代码
ACT_GE_PROPERTY:引擎初始化自动生成配置信息,用于引擎运行和流程执行
ACT_RE_DEPLOMENT:配置部署信息
ACT_GE_BYTEARRAY:给部署信息配置资源(bpmn & png文件资源)
ACT_RE_PROCDEF:给流程定义配置部署信息

4 启动流程

启动一个流程实例,流程实例也叫:ProcessInstance,启动一个流程实例表示开始一次业务流程的运行。在启动流程实例之前可以配置相应的业务需求,将某个业务绑定到当前流程上

java 复制代码
    @Test
    public void startProcessTest(){
        // 流程实例运行服务启动一个流程实例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 根据流程定义的id来启动一个流程实例
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection");
        System.out.println("流程定义id:"+instance.getProcessDefinitionId());
        System.out.println("流程实例id:"+instance.getId());
        System.out.println("当前活动id:"+instance.getActivityId());

    }

5 用户查询待办任务(Task)

将系统的业务流程已经交给activiti管理,通过activiti就可以查询当前流程执行到哪里了,当前用户需要办理什么任务,activiti帮我们管理执行操作

java 复制代码
    @Test
    public void qryHistoryActInsts(){
        // 根据流程定义或者流程实例查询对应的历史执行流程
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
        // 查询历史场景1:根据流程实例查询历史执行流程
        instanceQuery.processInstanceId("7501");
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
        System.out.println("根据流程实例查询历史执行流程");
        for (HistoricActivityInstance instance:instanceQuery.list()) {
            System.out.println("活动id"+instance.getActivityId());
            System.out.println("活动名称"+instance.getActivityName());
            System.out.println("活动类型"+instance.getActivityType());
        }
        // 查询历史场景2:根据流程定义查询历史执行流程
        instanceQuery.processDefinitionId("myEvection:1:5004");
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
        System.out.println("根据流程定义查询历史执行流程");
        for (HistoricActivityInstance instance:instanceQuery.list()) {
            System.out.println("活动id"+instance.getActivityId());
            System.out.println("活动名称"+instance.getActivityName());
            System.out.println("活动类型"+instance.getActivityType());
        }
    }

6 完成指定任务

java 复制代码
    @Test
    public void completTaskByProcdefAndProcUser(){
        // 根据流程定义和该流程定义中的任务用户获取到相关任务,并将该任务设置为完成
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("myEvection").taskAssignee("rose").list();
        for (Task task:taskList) {
            System.out.println("任务Id:"+task.getId());
            System.out.println("任务名称:"+task.getName());
            System.out.println("流程定义名称:"+task.getProcessDefinitionId());
            System.out.println("流程定义名称:"+task.getTaskDefinitionKey());
            taskService.complete(task.getId());
        }

    }

7 用户已办任务历史记录

用户可以查询已经办理的业务和正在处理的任务,查询历史任务表获得具体流程执行细节,当一个流程没有下一节点时,整个流程实例就执行结束。

java 复制代码
    @Test
    public void qryHistoryActInsts(){
        // 根据流程定义或者流程实例查询对应的历史执行流程
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
        // 查询历史场景1:根据流程实例查询历史执行流程
        instanceQuery.processInstanceId("7501");
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
        System.out.println("根据流程实例查询历史执行流程");
        for (HistoricActivityInstance instance:instanceQuery.list()) {
            System.out.println("活动id"+instance.getActivityId());
            System.out.println("活动名称"+instance.getActivityName());
            System.out.println("活动类型"+instance.getActivityType());
        }
        // 查询历史场景2:根据流程定义查询历史执行流程
        instanceQuery.processDefinitionId("myEvection:1:5004");
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
        System.out.println("根据流程定义查询历史执行流程");
        for (HistoricActivityInstance instance:instanceQuery.list()) {
            System.out.println("活动id"+instance.getActivityId());
            System.out.println("活动名称"+instance.getActivityName());
            System.out.println("活动类型"+instance.getActivityType());
        }
    }
相关推荐
合作小小程序员小小店2 小时前
web开发,在线%小区,物业%管理系统,基于idea,html,jsp,java,ssm,mysql数据库
java·数据库·mysql·jdk·intellij-idea
豐儀麟阁贵2 小时前
6.2 Object类
java·开发语言·python
Eric_Makabaka2 小时前
微服务重要知识点
java
lkbhua莱克瓦242 小时前
Java进阶——集合进阶(MAP)
java·开发语言·笔记·github·学习方法·map
u0119608232 小时前
java 不可变集合讲解
java·开发语言
Qiuner2 小时前
Spring Boot 进阶:application.properties 与 application.yml 的全方位对比与最佳实践
java·spring boot·后端
寒山李白2 小时前
Mybatis使用教程之XML配置方式实现增删改查
xml·java·mybatis
Seven973 小时前
剑指offer-38、⼆叉树的深度
java
Kapaseker3 小时前
一文入门 Java Stream
java