camunda最终章-springboot

1.实现并行流子流程

1.画图

 2.创建实体

package com.jmj.camunda7test.subProcess.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Cooker implements Serializable {public static final List<Cooker> repositoryCooker = new ArrayList();static {repositoryCooker.add(new Cooker("1","张三"));repositoryCooker.add(new Cooker("2","李四"));}private String cookerId;private String cookerName;}
package com.jmj.camunda7test.subProcess.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dish implements Serializable {public static final List<Dish> repositoryDish = new ArrayList();public static final Map<String,List<Dish>> relationDish = new HashMap<>();static {Dish dish1 = new Dish("1", "番茄炒蛋");Dish dish2 = new Dish("2", "青椒炒肉");Dish dish3 = new Dish("3", "蚂蚁上树");Dish dish4 = new Dish("4", "蛋炒饭");Dish dish5 = new Dish("5", "锅包肉");repositoryDish.add(dish1);repositoryDish.add(dish2);repositoryDish.add(dish3);repositoryDish.add(dish4);repositoryDish.add(dish5);relationDish.put("1",new ArrayList<>(){{add(dish1);add(dish2);add(dish3);}});relationDish.put("2",new ArrayList<>(){{add(dish4);add(dish5);}});}private String dishId;private String dishName;
}

3.注入对象

  @Autowiredprivate RepositoryService repositoryService;@Autowiredprivate RuntimeService runtimeService;@Autowiredprivate TaskService taskService;

4.部署流程

    @Testvoid depoly() {repositoryService.createDeployment().name("做菜流程").addClasspathResource("bpmn/做菜流程.bpmn")//绑定需要部署的流程文件.enableDuplicateFiltering(true).deploy();}

5.启动流程

   private static final String cookerIdList = "cookerIdList";@Testvoid createProcess() {Map<String, Object> map = new HashMap<>();map.put(cookerIdList, Cooker.repositoryCooker);ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("chi-fan-process", "chi-fan", map);System.out.println("流程启动成功: 流程实例ID=" + processInstance.getProcessInstanceId());String processInstanceId = processInstance.getProcessInstanceId();Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();System.out.println("生成的任务Id:" + task.getId() + "任务名:" + task.getName());taskService.claim(task.getId(), "jmj");System.out.println("将任务委托给jmj");}

6.一系列执行

private static final String jmj = "jmj";@Testvoid queryTaskInfo() {Task task = taskService.createTaskQuery().taskAssignee("jmj").list().get(0);System.out.println("任务是否处于悬停状态:" + task.isSuspended());System.out.println("设置任务一些参数");String id = task.getId();String processInstanceId = task.getProcessInstanceId();//那两个方法实际是一样的
//        runtimeService.setVariableLocal(processInstanceId,"local","jaa");taskService.setVariableLocal(id, "localTask", "bbb");}@Testvoid completeFirsCreate() {Task task = taskService.createTaskQuery().taskAssignee("jmj").list().get(0);taskService.complete(task.getId());}@Testvoid subExecutionQuery() {List<Execution> list = runtimeService.createExecutionQuery().processDefinitionKey("chi-fan-process").list();for (Execution execution : list) {System.out.println(execution.isEnded());System.out.println(execution.isSuspended());System.out.println(execution.getId());}}@Testvoid subTaskQuery() {Cooker cooker = Cooker.repositoryCooker.get(0);String cookerId = cooker.getCookerId();List<Task> list = taskService.createTaskQuery().taskAssignee(cookerId).processDefinitionKey("chi-fan-process").list();for (Task task : list) {String id = task.getId();String name = task.getName();String assignee = task.getAssignee();System.out.println(id + " " + name + " " + assignee);}List<Dish> dishes = Dish.relationDish.get(cookerId);System.out.println(dishes);Task task = list.get(0);String id = task.getId();//        Map<String, Object> variables = taskService.getVariables(id);Map<String, Object> variables = runtimeService.getVariables(task.getExecutionId());System.out.println("所有的流程变量:" + variables.size());variables.forEach((k, v) -> {System.out.println(k + " = " + v);});//给的是实例就是全局 给的是执行器就是 局部runtimeService.setVariable("123", "subtaskxTask", "这应该是执行器的作用域3");//全局//        Object subtaskxTask = runtimeService.getVariable(task.getProcessInstanceId(), "subtaskxTask");
//        System.out.println(subtaskxTask);//3
//        Object subtaskxTask1 = runtimeService.getVariable(task.getExecutionId(), "subtaskxTask");
//        System.out.println(subtaskxTask1);//1
//        taskService.setVariable(id,"subtask2Task2","测试子任务2的局部流程变量,这应该是实例作用域");//执行器}@Testvoid completeSubTask() {Map<String, Object> map = new HashMap<>();map.put("测试是什么位置的", 1);taskService.complete("95e204a4-3cd6-11ef-b405-005056c00008", map);//map是最外层的流程变量}@Testvoid q() {Task task = taskService.createTaskQuery().taskId("95e204a4-3cd6-11ef-b405-005056c00008").singleResult();//执行完一个任务就不存在了System.out.println(task);}//作用域 任务id>执行器>实例@Testvoid querySubExecutionId() {Cooker cooker = Cooker.repositoryCooker.get(0);String cookerId = cooker.getCookerId();List<Task> list = taskService.createTaskQuery().taskAssignee(cookerId).processDefinitionKey("chi-fan-process").list();Task task = list.get(0);Map<String, Object> variables = taskService.getVariables(task.getId());System.out.println(variables.size());variables.forEach((k, v) -> {System.out.println(k + " = " + v);});//        taskService.setVariableLocal(task.getId(),"tset","测试局部任务作用域");//作用域ID为taskId //代表当前任务
//        runtimeService.setVariableLocal(task.getExecutionId(),"tset","测试局部任务作用域12");//作用域ID为executeId 执行器代表当前流程//子流程的一级父类的变量需要等所有子流程结束后,才会消失 二级执行器就是一个流程执行完生命周期,就消失taskService.complete(task.getId());//只会去除任务ID作用域下的变量//执行器ID等于流程实例ID}//任务ID 可以拿到当前流程的执行器ID

2.如何废弃一个流程

  @Testvoid deleteAnProcess() {runtimeService.deleteProcessInstance("31a61f25-3cf1-11ef-b3cd-005056c00008","测试删除");}

3.总结

  1. 关于作用域有三种,其一是 父流程实例作用域,其二子流程实例作用域,最后是任务作用域,三种作用域,从前往后,后面的作用域可以获取前面的作用域的流程变量,而前面的不能获取后面的流程变量
  2. 流程实例ID其实就等于执行器ID,在一个任务下,给执行器ID作作用域,其实就是给当前流程实例作全局变量。
  3. runtimeService与taskService里 getVariable 与 getVariableLocal 的区别,前者的参数是执行器ID,也就当前流程作用域下的变量,如果没有子流程,则就是获取全局的流程变量,如果有子流程,就是获取子流程与父流程所拥有的流程变量,而 getVariableLocal 仅仅获取此作用域下的变量,不会拿到父类作用域下的变量。同理 taskService  getVariable  是拿当前任务作用域 以及当前子流程作用域 以及父流程作用域下的全局变量, getVariableLocal只是获取当前任务作用域下的变量。
  4. 作用域下如果有相同名字的变量,则会拿到离自己作用域最近的值。
  5. 子流程获取不到另一个子流程的流程变量,若要互相传递参数,则可以放入父流程的全局变量
  6. claim方法其实和 setAssignee 差不多,区别就是, setAssignee可以用无限次,而claim设定以后,再次设定就会报错,设置了Assignee就相当于设置了claim。
  7. 子流程他其实创建的时候,会先创建多实例子流程体,然后每个子流程实例会有一个框框执行器,框框执行器继承多实例子流程体,框框执行器里面才是执行流程体,这个框框执行器就是给每个子流程放入子流程独立的全局变量(传入集合参数)用的。  若两个子流程,会创建一个实例执行器(没有父ID,因为就是流程本身),两个框框执行器(继承多实例子流程体),两个子流程执行器(分别继承框框执行器)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第230题二叉搜索树中第K小的元素

题目&#xff1a; 题解&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int search_num(struct TreeNode* root, int k, int *result, int num) {if(num k 1){retu…

FastGPT连接OneAI接入网络模型

文章目录 FastGPT连接OneAI接入网络模型1.准备工作2.开始部署2.1下载 docker-compose.yml2.2修改docker-compose.yml里的参数 3.打开FastGPT添加模型3.1打开OneAPI3.2接入网络模型3.3重启服务 FastGPT连接OneAI接入网络模型 1.准备工作 本文档参考FastGPT的官方文档 主机ip接…

记一次若依框架和Springboot常见报错的实战漏洞挖掘

目录 前言 本次测实战利用图​ 1.判段系统框架 2.登录页面功能点测试 2.1 弱口令 2.2 webpack泄露信息判断 2.3 未授权接口信息发现 3.进一步测试发现新的若依测试点 3.1 默认弱口令 3.2 历史漏洞 4.访问8080端口发现spring经典爆粗 4.1 druid弱口令 4.2 SwaggerU…

浅析Kafka-Stream消息流式处理流程及原理

以下结合案例&#xff1a;统计消息中单词出现次数&#xff0c;来测试并说明kafka消息流式处理的执行流程 Maven依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusio…

音频语言学习领域数据集现状、分类及评估

Audio Language Learning (Audio-Text Learning) 是一个新兴的研究领域&#xff0c;专注于处理、理解和描述声音。它的发展动力是机器学习技术的进步以及越来越多地将声音与其相应的文本描述相结合的数据集的可用性。 Audio Language Models (ALMs) 是这个领域的关键技术&#…

MATLAB中的SDPT3、LMILab、SeDuMi工具箱

MATLAB中的SDPT3、LMILab、SeDuMi工具箱都是用于解决特定数学优化问题的工具箱&#xff0c;它们在控制系统设计、机器学习、信号处理等领域有广泛的应用。以下是对这三个工具箱的详细介绍&#xff1a; 1. SDPT3工具箱 简介&#xff1a; SDPT3&#xff08;Semidefinite Progra…

基于QT开发的反射内存小工具

前言 最近项目需要需要开发一个反射内存小工具&#xff0c;经过2天的修修改终于完成了。界面如下&#xff1a; 功能简介 反射内存指定地址数据读取反射内存指定地址数据写入反射内存指定地址数据清理十进制、十六进制、二进制数据相互转换 部分代码 void RfmMain::setWOthe…

攻防世界(PHP过滤器过滤)file_include

转换过滤器官方文档&#xff1a;https://www.php.net/manual/zh/filters.convert.php#filters.convert.iconv 这道题因为convert.base64-encode被过滤掉了&#xff0c;所以使用convert.iconv.*过滤器 在激活 iconv 的前提下可以使用 convert.iconv.* 压缩过滤器&#xff0c; 等…

Win10安装MongoDB(详细版)

文章目录 1、安装MongoDB Server1.1. 下载1.2. 安装 2、手动安装MongoDB Compass(GUI可视工具)2.1. 下载2.2.安装 3、测试连接3.1.MongoDB Compass 连接3.2.使用Navicat连接 1、安装MongoDB Server 1.1. 下载 官网下载地址 https://www.mongodb.com/try/download/community …

利用docker容器安装node,使用vue的开发环境

目录 vue-app ├── docker-data │ ├── site │ ├── app ├── docker-compose.yaml └── deploy.sh docker-compose.yaml yaml文件执行 version: 3.8services:node:image: node:latestcontainer_name: vue-appports:- "8080:8080" # 宿主8080映射容器8…

系统服务综合项目

要求&#xff1a; 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在 /nfs/rhce 目录 5、该目录由 no…

如何保证语音芯片的稳定性能和延长使用寿命

要让语音芯片保持稳定性能&#xff0c;首先需要深入理解其工作原理和内部构造。语音芯片&#xff0c;作为现代电子设备中的核心组件之一&#xff0c;承载着声音信号的处理与输出功能。为了确保其稳定运行&#xff0c;我们需要从多个方面进行细致的考虑和操作。‌ 1、避免长期高…

Windows系统MySQL的安装,客户端工具Navicat的安装

下载mysql安装包&#xff0c;可以去官网下载&#xff1a;www.mysql.com。点击downloads 什么&#xff1f;后面还有福利&#xff1f; 下载MySQL 下载企业版&#xff1a; 下载Windows版 5点多的版本有点低&#xff0c;下载8.0.38版本的。Window系统。下载下面的企业版。不下载…

[数字图像处理]基础知识整理(部分,持续更新)

程序中描述一副图像&#xff0c;已知其横向纵向的像素个数即可&#xff08;&#xff09; 灰度直方图能反映一副图像各个灰度级像素占图像的面积比&#xff08;√&#xff09; 从程序编写的角度看&#xff0c;描述一副图像的基本属性通常包括其分辨率&#xff0c;即图像的宽度…

Docker镜像和容器的管理

1 Docker镜像管理操作 开启镜像加速 根据关键字查询镜像 下载查看镜像 详细镜像信息 查看latest版本 上传镜像到阿里云仓库 2 Docker容器操作 关于容器根据第一个pid进程是否能正常在前台运行

19. 地址转换

地址转换 题目描述 Excel 是最常用的办公软件。每个单元格都有唯一的地址表示。比如&#xff1a;第 12 行第 4 列表示为&#xff1a;"D12"&#xff0c;第 5 行第 255 列表示为"IU5"。 事实上&#xff0c;Excel 提供了两种地址表示方法&#xff0c;还有一…

算法训练营第30天|122.买卖股票的最佳时机II|55. 跳跃游戏|45.跳跃游戏II|1005.K次取反后最大化的数组和

122.买卖股票的最佳时机II 思路&#xff1a;只有前一天与后一天的利润为正时&#xff0c;才将其加入总利润。 55. 跳跃游戏 思路&#xff1a;找最大覆盖范围 出错点&#xff1a;数组的遍历&#xff0c;遍历范围应该是覆盖范围内 45.跳跃游戏II 思路&#xff1a; 局部最优&am…

批量爬取B站网络视频信息

使用XPath爬取B站视频链接等相关信息 分析B站html框架获取内容完整代码 对于B站&#xff0c;目前网上的爬虫大多都是使用通过解析服务器的响应来爬取想要的内容&#xff0c;下面我们通过使用XPath来爬取B站上一些想要的信息 此次任务我们需要对B站搜索到的关键字&#xff0c;并…

数据结构 —— FloydWarshall算法

数据结构 —— FloydWarshall算法 FloydWarshall算法三种最短路径算法比较1. Dijkstra算法2. Bellman-Ford算法3. Floyd-Warshall算法总结 我们之前介绍的两种最短路径算法都是单源最短路径&#xff0c;就是我们要指定一个起点来寻找最短路径&#xff0c;而我们今天介绍的Floyd…

ctfshow-web入门-文件上传(web166、web167)(web168-web170)免杀绕过

目录 1、web166 2、web167 3、web168 4、web169 5、web170 1、web166 查看源码&#xff0c;前端只让传 zip 上传 zip 成功后可以进行下载 随便搞一个压缩包&#xff0c;使用记事本编辑&#xff0c;在其内容里插入一句话木马&#xff1a; 上传该压缩包&#xff0c;上传成功…