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…

《Foundation 侧边栏》

《Foundation 侧边栏》 介绍 Foundation 是一个强大的前端框架,它提供了一套丰富的工具和组件,帮助开发者快速构建响应式、移动优先的网站和应用程序。在 Foundation 中,侧边栏是一个常用的组件,用于展示导航链接、菜单或其他相关信息。本文将详细介绍如何在 Foundation …

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接…

JDBC 实例分享——简易图书管理系统

目录 前言 数据表的建立 操作包各个类的实现 增加类 删除类 展示类 借阅与归还类 前言 书接上文 JDBC编程的学习——MYsql版本-CSDN博客 本期我们通过对先前图书管理系统进行改造,是它的数据能保存在数据库中 完整代码我已经保存在github中,能不能给个星呢!!!! call…

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

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

热键危机:揭秘Memcached中的热键问题及其解决方案

热键危机&#xff1a;揭秘Memcached中的热键问题及其解决方案 Memcached是一种广泛使用的高性能分布式内存缓存系统&#xff0c;它通过缓存数据来减少对后端数据库的访问压力&#xff0c;从而提高应用性能。然而&#xff0c;Memcached也可能遇到热键&#xff08;hot key&#…

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

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

Okhttp实现原理

OkHttp 是一个高效的 HTTP 客户端库&#xff0c;广泛应用于 Android 和 Java 应用中。它提供了简洁的 API&#xff0c;支持多种协议&#xff0c;如 HTTP/1.x 和 HTTP/2&#xff0c;并且内置了缓存和重试机制。下面是结合源码分析的 OkHttp 的实现原理&#xff1a; 核心组件 O…

Swift 数据类型

Swift 数据类型 Swift 是一种强类型语言,这意味着在 Swift 中声明的每个变量和常量都必须具有明确的类型。Swift 的类型系统旨在帮助开发者编写清晰、安全的代码。本文将详细介绍 Swift 中的基本数据类型,包括整数、浮点数、布尔值、字符和字符串。 整数类型 Swift 提供了…

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

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…

SqlSugar-使用SqlSugar进行多数据库操作

使用SqlSugar进行多数据库操作主要涉及以下几个步骤&#xff1a; 1. 配置数据库连接 首先&#xff0c;你需要在项目的配置文件中&#xff08;如appsettings.json、web.config或app.config&#xff09;配置多个数据库的连接字符串。每个连接字符串都对应一个不同的数据库。 例…

攻防世界(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 …

【第28章】MyBatis-Plus之插件主体

文章目录 前言一、MybatisPlusInterceptor 概览1. 属性2. InnerInterceptor 接口 二、使用示例1.Spring 配置2.Spring Boot 配置3 .mybatis-config.xml 配置 三、拦截忽略注解 InterceptorIgnore四、手动设置拦截器忽略执行策略五、本地缓存 SQL 解析总结 前言 MyBatis-Plus 提…

android 固定图片大小

在Android中&#xff0c;固定图片大小可以通过多种方法实现&#xff0c;这些方法主要涉及到ImageView控件的使用、Bitmap类的操作&#xff0c;以及第三方库&#xff08;如Glide&#xff09;的辅助。以下是几种常见的方法&#xff1a; 1. 使用ImageView控件 在Android的布局文…

利用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、避免长期高…