当前位置: 首页 > news >正文

在Springboot集成Activiti工作流引擎-引入、调用,测试【基础讲解】

工作流 通过计算机对业务流程自动化执行管理
他主要解决的是使在多个参与者之间按照某种“预定义规则”自动进行传递稳定 信息或任务的过程
通俗来讲 业务上一个玩着的审批流程 比如请假,出差 外出采购等

工作流引擎就是来解决流程问题的 提高我们的工作效率

如果没有工作流引擎 我们就需要自己去写逻辑 就特别的复杂 扩展性还不强

使用工作流引擎 业务改变,不需要修改代码
如果是我们自己写的逻辑 有可能 业务改变,代码也需要改变

那么为什么工作流引擎不用修改代码
因为我们的工作流引擎都实现了一个规范
这个规范要求我们的流程管理与状态字段无关,始终都是读取业务流程图的下一个节点
当业务发生改变我们只需要更新业务流程图即可

常见的工作流引擎有
Activiti、jBPM、Camunda、Flowable 还有我们国产的盘古BPM、云程

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

建模语言BPMN
BPM 意思就是 业务流程管理,
BPM 软件根据企业中业务环节的变化,推进人与人之间,人与系统之间以及系统与系统之间的整理及调整的经营方法和解决方案的IT工具

BPMN 意思就是 业务流程模型和符号,是一套标准的业务流程建模符号 Activiti就是使用BPMN 进行流程建模和流程执行管理

事件 Event

开始 表示一个流程的开始
中间 发生的开始和结束事件之间,影响处理流程
结束 表示该过程结束
在这里插入图片描述

活动 Activities

活动是工作或任务的一个通用术语,一个活动也可以是一个任务还是可以是一个当前流程的子处理流程
其次 你还可以为活动指定不同的类型
比如
用户任务-> 服务任务-> 子流程
在这里插入图片描述

网关 GateWay

用于表示流程的分支与合并
排他网关 并行网关 包容网关 综合网关 事件网关

在这里插入图片描述

排他网关 只有一条路径会被选择
并行网关 所有路径都会被同时选择
包容网关 可以同时执行多条线路,也可以在网关上设置条件
事件网关 专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件
当流程执行到事件网关后,流程处于等待状态,需要等抛出事件才能将等待状态转换为活动状态

在这里插入图片描述

流向 Flow
流是连接两个流程节点的连线
顺序流:用一个带实心箭头的实心线表示,用于指定活动执行顺序
信息流:用一条带箭头的虚线表示,用于描述两个独立的业务参与者之间发送和接受的消息流动
关联: 用一根带有线箭头的点线表示,用于将相关的数据,文本,和其他人工信息与流对象联系起来
用于展示活动的输入和输出

在这里插入图片描述

Activiti的使用流程

第一步 引入依赖并初始化数据库
引入依赖

第二步 通过工具绘画流程图
通过Activiti流程建模工具定义业务流程 生成(.bpmn文件)
.bpmn文件就是业务流程定义文件 通过xml定义业务流程

第三步 流程定义部署
向Activiti部署业务流程定义(.bpmn文件) 使用Activiti提供的api向Activiti中部署.bpmn文件
通俗一点就是 让Activiti认识要使用的流程

第四步 启动一个流程实例
启动一个流程实例表示开始一次业务流程的运行

第五步 用户查询代办任务
因为现在流程的业务交给了Activiti管理 通过Activiti就可以查询当前流程执行到那里了
当前用户需要执行什么任务 这些Activiti都会帮我们管理
我们学习了Activiti的API 就可以了

第六步 用户办理任务
用户查询代办任务后,就可以办理某个任务,如果这个任务办理还需要其他用户办理,也不需要我们写代码
Activiti 帮我们完成了

第七步 流程结束

Activiti 数据库支持 mysql 等

项目使用

第一步 引入依赖

    <dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.1.0.M6</version><exclusions><exclusion><artifactId>mybatis</artifactId><groupId>org.mybatis</groupId></exclusion></exclusions></dependency>

activiti 默认集成了Security 安全框架,当前我们项目里已经集成了Security 后续设置审批人必须是系统用户
否则会报错

第二步 添加配置

springactiviti:#    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)#    true:表不存在,自动创建(开发使用)#    create_drop: 启动时创建,关闭时删除表(测试使用)#    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)database-schema-update: true#监测历史表是否存在,activities7默认不开启历史表db-history-used: true#none:不保存任何历史数据,流程中这是最高效的#activity:只保存流程实例和流程行为#audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值#full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数history-level: full#校验流程文件,默认校验resources下的process 文件夹的流程文件check-process-definitions: true

第三步:启动项目后 如果表不存在 会自动创建

表介绍
act_re re表示repository 这个前缀包含了定义和流程静态资源
act_ru ru表示runtime 表示表运行时
act_hi hi表示history 历史数据
act_ge ge表示general 通用数据
在这里插入图片描述
在这里插入图片描述

第四步 activiti 设计工具

官网下载地址
https://www.activiti.org/#get-started
官方提供的一个工具
Activiti Modeler
这个工具是 war包 测试的话 自行去搭建 tomcat

地址 localhost:8080/activiti-explorer
默认用户名 密码
kermit kermit

在这个系统里 生成流程后 然后 导出 xml和 流程图片

然后把这两个资源 导入到resources 里
导入也可以用压缩包方式导入
这些操作 就不写了

然后测试

1. 流程定义部署

    @Testpublic void deployProcess(){Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/qingjia.bpmn20.xml").addClasspathResource("process/qingjia.png").name("请假流程").deploy();System.out.println(deploy.getId());System.out.println(deploy.getName());}

2. 启动一个流程实例

  //启动实例@Testpublic void startProcess(){ProcessInstance qingjia = runtimeService.startProcessInstanceByKey("qingjia");System.out.println("流程定义ID"+qingjia.getProcessDefinitionId());System.out.println("流程实例ID"+qingjia.getId());System.out.println("流程活动ID"+qingjia.getActivityId());}

3. 用户查询代办任务

    //查询个人代办任务 -- zhangsan@Testpublic void findTaskList(){String name="zhangsan";List<Task> taskList = taskService.createTaskQuery().taskAssignee(name).list();taskList.forEach(item->{System.out.println("流程实例的ID"+item.getProcessInstanceId());System.out.println("任务id"+item.getId());System.out.println("任务负责人"+item.getAssignee());System.out.println("任务名称"+item.getName());});}

4. 用户办理任务 (处理任务)

    @Testpublic void completTask(){String name="zhangsan";//查询负责人需要处理的任务 返回一条Task task = taskService.createTaskQuery().taskAssignee(name).singleResult();//处理任务 参数就是idtaskService.complete(task.getId());//完成后会自动到下一个节点}

5. 查询已经处理的任务

   @Testpublic void findcompleteTaskList(){String name="zhangsan";List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().taskAssignee(name).finished().list();list.forEach(item->{System.out.println("流程实例的ID"+item.getProcessInstanceId());System.out.println("任务id"+item.getId());System.out.println("任务负责人"+item.getAssignee());System.out.println("任务名称"+item.getName());});}

====================================

什么叫流程实例
流程定义 ProcessDefinition和流程实例ProcessInstance是 activiti重要概念
类似于java类和java实例的关系
启动一个流程实例就是启动一个业务流程的运行
一个业务流程就要启动一个实例

让实际业务和activiti表关联(BusinessKey)
比如我们填写了一个请假单 一定会有一个请假单的唯一标识
通常会使用这个标识来关联activiti 这个标识在activiti中成为BusinessKey

BusinessKey:业务标识,通常为业务主键,业务标识和流程标识一一对应
业务标识来源于业务系统,存储业务标识就是根据业务标识来关联查询业务系统数据

举例 请假启动一个流程实例,将请假单的id作为业务标识存储到activiti中
将来查询activiti的流程实例信息就可以获取请假单的id从而关联查询业务系统里的请节单数据

测试:

 //启动实例 添加BusinessKey@Testpublic void startProcessBusinessKey(){//startProcessInstanceByKey 参数二ProcessInstance qingjia = runtimeService.startProcessInstanceByKey("qingjia","1001");System.out.println("流程定义ID"+qingjia.getProcessDefinitionId());System.out.println("流程实例ID"+qingjia.getId());System.out.println("流程活动ID"+qingjia.getActivityId());System.out.println("BusinessKey-业务id"+qingjia.getBusinessKey());}

==================================================================

挂起,激活流程实例

应用场景
比如 公司每个月的最后一天 需要封账,这个时候申请的报销审批 就可以挂起

  1. 全部流程实例挂起
    @Testpublic void suspendProcessInstance(){//1.获取流程定义对象ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult();//2. 调用流程定义对象的方法判断当前状态:挂起 还是激活boolean suspended = qingjia.isSuspended();//3. 判断挂起还是激活//如果 true 挂起状态 就要让他激活if(suspended){//那就执行激活//第一个参数 流程定义的id// 第二个参数 是否激活 true// 第三个参数 时间点repositoryService.activateProcessDefinitionById(qingjia.getId(),true,null);System.out.println("激活了");}else{repositoryService.suspendProcessDefinitionById(qingjia.getId(),true,null);System.out.println("挂起了");}}
  1. 单个的流程实例挂起
   @Testpublic void suspendProcessInstanceOne(){ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId("流程实例ID").singleResult();boolean suspended = processInstance.isSuspended();//如果 true 挂起状态 就要让他激活if(suspended){//那就执行激活//第一个参数 流程定义的id// 第二个参数 是否激活 true// 第三个参数 时间点runtimeService.activateProcessInstanceById("流程实例ID");System.out.println("激活了");}else{runtimeService.startProcessInstanceByKey("流程实例ID");System.out.println("挂起了");}}

相关文章:

在Springboot集成Activiti工作流引擎-引入、调用,测试【基础讲解】

工作流 通过计算机对业务流程自动化执行管理 他主要解决的是使在多个参与者之间按照某种“预定义规则”自动进行传递稳定 信息或任务的过程 通俗来讲 业务上一个玩着的审批流程 比如请假&#xff0c;出差 外出采购等 工作流引擎就是来解决流程问题的 提高我们的工作效率 如果…...

Java书签 #解锁MyBatis的4种批量插入方式及ID返回姿势

1. 今日书签 项目开发中&#xff0c;我们经常会用到单条插入和批量插入。但是实际情况可能是&#xff0c;项目初期由于种种原因&#xff0c;在业务各处直接使用单条插入SQL进行开发&#xff08;未开启批处理&#xff09;&#xff0c;在后面的迭代中&#xff0c;系统性能问题渐…...

在react项目中如何引入国际化

react-i18next 在 React 项目中引入国际化&#xff08;Internationalization&#xff0c;简称 i18n&#xff09;可以使用第三方库来实现。其中&#xff0c;最常用且流行的国际化库是 react-i18next&#xff0c;它基于 i18next 实现&#xff0c;提供了方便易用的国际化功能。下…...

spring学习笔记十三

注解实现管理第三方Bean和为第三方Bean注入资源 1、添加pom坐标 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency> 2、SpringConfig配置类 Configuratio…...

react native 本地存储 AsyncStorage

An asynchronous, unencrypted, persistent, key-value storage system for React Native. Async Storage 只能用来储存字符串数据&#xff0c;所以为了去储存object类型的数据&#xff0c;得先进行序列化&#xff08;JSON.stringify()&#xff09;当你想要使用数据的时候&…...

Postgresql数据库中的时间类型汇总

PostgreSQL数据库有以下几种时间类型 1 日期 date&#xff1a;表示日期&#xff0c;格式为YYYY-MM-DD。 2 时间 time&#xff1a;表示时间&#xff0c;格式为HH:MI:SS。 3 日期和时间 timestamp&#xff1a;表示日期和时间&#xff0c;格式为YYYY-MM-DD HH:MI:SS。 4 带…...

算法刷题Day 51 最佳买卖股票时机含冷冻期+买卖股票的最佳时期含手续费

Day 51 动态规划 309. 最佳买卖股票时机含冷冻期 关键是要画出状态转移图 然后根据状态转移图来写状态转移方程 class Solution { public:int maxProfit(vector<int>& prices) {int len prices.size();vector<vector<int>> dp(len, vector<int&g…...

编程导航算法村 第五关 | 白银挑战

编程导航算法村 第五关 | 白银挑战 用栈实现队列 LeetCode 232题 class MyQueue {private Stack<Integer> stack; // 保存private Stack<Integer> tempstack; // 临沭队列public MyQueue() {stack new Stack<>();tempstack new Stack<>();}public…...

(十六十七)时序数据库是怎么存储用户名和密码的从InfluxDB OSS迁移数据

以下内容来自 尚硅谷&#xff0c;写这一系列的文章&#xff0c;主要是为了方便后续自己的查看&#xff0c;不用带着个PDF找来找去的&#xff0c;太麻烦&#xff01; 第 16 章 时序数据库是怎么存储用户名和密码的 1、InfluxDB内部自带了一个用Go语言写的BlotDB&#xff0c;Blo…...

5分钟开发一个AI论文抓取和ChatGPT提炼应用

5分钟开发一个AI论文抓取和ChatGPT提炼应用 第一步 点击“即刻开始” -选择模板 python -修改标题 “AIPaper”&#xff0c;项目标识“AIPaper”&#xff0c;点击“创建项目” 第二步 在编程区域右侧AI区域&#xff0c;输入框输入以下内容&#xff1a; 请根据下面的内容&…...

SK5代理与网络安全:保障爬虫隐匿性与HTTP连接稳定性

一、SK5代理简介 SK5代理&#xff0c;即socks5代理&#xff0c;是一种网络协议&#xff0c;用于在客户端和服务器之间进行数据传输。相比其他代理协议&#xff0c;如HTTP代理&#xff0c;SK5代理具有更高的性能和安全性&#xff0c;支持TCP和UDP连接&#xff0c;并可以处理更复…...

基于4G网络的嵌入式设备远程升级系统设计与实现(学习一)

摘要 随着无线通信技术的不断更新发展&#xff0c;嵌入式设备的联网应用领域得以大规模扩大&#xff0c;远程升级功能成为产品开发中必不可少的一部分。 本文对嵌入式设备远程升级进行了研究&#xff0c;在不改变设备硬件集成度基础上&#xff0c;设计实现了分离式升级的远程…...

陪诊小程序软件|陪诊系统定制|医院陪诊小程序

开发一个陪诊小程序需要投入一定的费用&#xff0c;具体金额会因项目的复杂程度、功能需求和推广政策而有所差异在投入资金之前&#xff0c;建议进行市场调研和需求分析&#xff0c;制定出合理的预算&#xff0c;并选择专业的开发团队进行合作&#xff0c;那么开发陪诊小程序需…...

[数据集][目标检测]空中飞鸟目标检测数据集VOC格式4955张

数据集名称&#xff1a;空中飞鸟数据集VOC-4955张 数据集制作单位&#xff1a;未来自主研究中心(FIRC) 图片数量(jpg文件个数)&#xff1a;4955 标注数量(xml文件个数)&#xff1a;4955 标注类别数&#xff1a;1 标注类别名称:["bird"] 每个类别标注的框数&#xff1…...

安徽现货黄金代理请看这篇

持续两三年的新冠疫情&#xff0c;令全球经济遭受不同程度的打击&#xff0c;很多传统的行业更是重灾区&#xff0c;当中不少从业多年的朋友表示虽然看不清前进&#xff0c;但也不敢随便转行&#xff0c;如果那么有一份这样的工作&#xff0c;既不用他们离开本职&#xff0c;也…...

HTML JS实现点击按钮下载文件功能例子(C知道版)

其实这篇应该算是一篇“水”文章&#xff0c;为什么要这么“水”呢&#xff0c;除了最近南方的气候闷热难耐需要降温之外&#xff0c;另一个主要原因&#xff0c;这里面所写的代码均是由CSDN的AI文本大模型"C知道"完成&#xff0c;我在这里只是简单记录一下&#xff…...

企业网络安全与数据保护合规建设 ——从合规运营到香港上市

序言 《企业网络安全与数据保护合规建设 ——从合规运营到香港上市&#xff08;一&#xff09;》梳理了我国网络安全与数据保护领域近期主要立法情况&#xff0c;本文将着重分析拟赴港上市企业运营阶段的数据合规要点以期为拟赴港上市的相关企业提供有益的参考。 二 企业运营…...

antdv Select dropdownRender Input 不能输入的问题

简言之&#xff1a;外层套div&#xff0c;然后利用Select的open属性。直接上代码&#xff1a; <template><a-form-item-rest><div click"selOpen !selOpen"><Selectv-model:value"xxx"placeholder"请选择":options"g…...

PostgreSQL 查询json/jsonb是否存在某个片段

文章目录 前言实现实现思路坑1坑2坑3 恍然大悟 前言 在PostgreSQL中&#xff0c;jsonb有额外的操作符&#xff0c;如 >、<、?、?|、?& 可以用来查询是否包含路径/值&#xff0c;以及顶层键值是否存在。 详细文章&#xff1a;PostgreSQL 操作json/jsonb 那么&am…...

Spring 官方文档及相关资料的网址集合

文章目录 MavenSpringSpring FrameworkSpring BootSpring Cloud AlibabaNacos Maven Maven 仓库依赖包官方查询通道&#xff1a;https://mvnrepository.com/ Maven 插件官方文档&#xff1a;https://maven.apache.org/plugins/ 安卓依赖包官方查询通道*&#xff1a;https://m…...

hypery 十一、命令行

教程&#xff1a;Hyperf symfony/console composer地址&#xff1a; symfony/console - Packagist github地址&#xff1a;GitHub - symfony/console: Eases the creation of beautiful and testable command line interfaces hyperf/command github地址:https://github.com/…...

QT占位符 %n+arg()、QString的格式化arg(补零/进制转换)

一、 1、QMessageBox::warning(this, tr("查找"), tr("找不到%1").arg(str)); 其中 %1为占位符&#xff0c;QMessageBox显示时&#xff0c;arg中的变量值会替代 %1占位符&#xff0c;达到在QMessageBox弹出框中输出变量的目的。 2、const QString entry…...

浙江大学第六周数据结构之06-图1 列出连通集

题目详情&#xff1a; 给定一个有N个顶点和E条边的无向图&#xff0c;请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时&#xff0c;假设我们总是从编号最小的顶点出发&#xff0c;按编号递增的顺序访问邻接点。 输入格式: 输入第1行给出2个整数N(0&…...

DNS缓存病毒防护43.227.220

DNS缓存病毒又称DNS欺骗&#xff0c;是一种通过查找并利用DNS系统中存在的漏洞&#xff0c;将流量从合法服务器引导至虚假服务器上的攻击方式。 在实际的DNS解析过程中&#xff0c;用户请求某个网站&#xff0c;浏览器首先会查找本机中的DNS缓存&#xff0c;如果DNS缓存中记录…...

Spring MVC -- 返回数据(静态页面+非静态页面+JSON对象+请求转发与请求重定向)

目录 1. 返回静态页面 2. 返回非静态页面 2.1 ResponseBody 返回页面内容 2.2 RestController ResponseBody Controller 2.3 示例:实现简单计算的功能 3. 返回JSON对象 3.1 实现登录功能&#xff0c;返回 JSON 对象 4. 请求转发(forward)或请求重定向(redirect) 4.1 请…...

k8s集群部署(使用kubeadm部署工具进行快速部署,相关对应版本为docker20.10.0+k8s1.23.0)

1. 安装要求 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#xff1a; 一台或多台机器&#xff0c;操作系统 CentOS7.x-86_x64硬件配置&#xff1a;2GB或更多RAM&#xff0c;2个CPU或更多CPU&#xff0c;硬盘20GB或更多可以访问外网&#xff0c;需要拉…...

SIP视频对讲sip广播网关

SV-PA2是专门对行业用户需求研发的一款SIP音视频对讲&#xff0c;媒体流传输采用标准IP/RTP/RTSP协议。它很好的继承了锐科达话机稳定性好、电信级音质的优点&#xff0c;且完美兼容当下所有基于SIP的主流IPPBX/软交换/IMS平台,如Asterisk, Broadsoft, 3CX, Elastix 等。它集多…...

prometheus直方图实践

目录 1.简介 2.方案 1.简介 Prometheus提供了Counter、Gauge、Histogram、Summary四类指标&#xff08;详见Metric types | Prometheus&#xff09;&#xff0c;可以通过"github.com/prometheus/client_golang/prometheus"自定义采集指标、注册、采集数据、发布UR…...

【C语言进阶篇】指针都学完了吧!那回调函数的应用我不允许还有人不会!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言&#x1f4ac; 函数指针数组&#x1f4ad; 函数指针数组的定义&#x1f4ad; 函数指针数组的…...

专注:如何提高专注力和注意力的简要指南

专注力和集中力可能很难掌控的很好。大多数人都想学习如何提高注意力和注意力。但真的做到了&#xff1f;我们生活在一个嘈杂的世界里&#xff0c;不断的分心会使注意力难以集中。 此指南包含有关如何获得并保持专注的研究。我们将分解提升您的思维并关注重要事物背后的理论依…...