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.注入对象
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
4.部署流程
@Test
void depoly() {
repositoryService.createDeployment()
.name("做菜流程").addClasspathResource("bpmn/做菜流程.bpmn")//绑定需要部署的流程文件
.enableDuplicateFiltering(true)
.deploy();
}
5.启动流程
private static final String cookerIdList = "cookerIdList";
@Test
void 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";
@Test
void 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");
}
@Test
void completeFirsCreate() {
Task task = taskService.createTaskQuery().taskAssignee("jmj").list().get(0);
taskService.complete(task.getId());
}
@Test
void 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());
}
}
@Test
void 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的局部流程变量,这应该是实例作用域");//执行器
}
@Test
void completeSubTask() {
Map<String, Object> map = new HashMap<>();
map.put("测试是什么位置的", 1);
taskService.complete("95e204a4-3cd6-11ef-b405-005056c00008", map);//map是最外层的流程变量
}
@Test
void q() {
Task task = taskService.createTaskQuery().taskId("95e204a4-3cd6-11ef-b405-005056c00008").singleResult();//执行完一个任务就不存在了
System.out.println(task);
}
//作用域 任务id>执行器>实例
@Test
void 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.如何废弃一个流程
@Test
void deleteAnProcess() {
runtimeService.deleteProcessInstance("31a61f25-3cf1-11ef-b3cd-005056c00008","测试删除");
}
3.总结
- 关于作用域有三种,其一是 父流程实例作用域,其二子流程实例作用域,最后是任务作用域,三种作用域,从前往后,后面的作用域可以获取前面的作用域的流程变量,而前面的不能获取后面的流程变量
- 流程实例ID其实就等于执行器ID,在一个任务下,给执行器ID作作用域,其实就是给当前流程实例作全局变量。
- runtimeService与taskService里 getVariable 与 getVariableLocal 的区别,前者的参数是执行器ID,也就当前流程作用域下的变量,如果没有子流程,则就是获取全局的流程变量,如果有子流程,就是获取子流程与父流程所拥有的流程变量,而 getVariableLocal 仅仅获取此作用域下的变量,不会拿到父类作用域下的变量。同理 taskService getVariable 是拿当前任务作用域 以及当前子流程作用域 以及父流程作用域下的全局变量, getVariableLocal只是获取当前任务作用域下的变量。
- 作用域下如果有相同名字的变量,则会拿到离自己作用域最近的值。
- 子流程获取不到另一个子流程的流程变量,若要互相传递参数,则可以放入父流程的全局变量
- claim方法其实和 setAssignee 差不多,区别就是, setAssignee可以用无限次,而claim设定以后,再次设定就会报错,设置了Assignee就相当于设置了claim。
- 子流程他其实创建的时候,会先创建多实例子流程体,然后每个子流程实例会有一个框框执行器,框框执行器继承多实例子流程体,框框执行器里面才是执行流程体,这个框框执行器就是给每个子流程放入子流程独立的全局变量(传入集合参数)用的。 若两个子流程,会创建一个实例执行器(没有父ID,因为就是流程本身),两个框框执行器(继承多实例子流程体),两个子流程执行器(分别继承框框执行器)。