创建流程实例
书接上回Camunda工作流集成SpringBoot(一)
注册流程相当于java中创建一个Class 后续的流程相当于该流程的一个一个的实例
首先需要给大家展示一下流程图的xml文件
后续我们会通过name创建流程类,通过id创建流程实例所以不要弄混了
@Autowired
RepositoryService repositoryService;
/**
* 注册流程
**/
@Test
public void registerProcesses(){
Deployment deployment = repositoryService.createDeployment().name("studyCamunda").addClasspathResource("BPMN/study.bpmn20.xml").deploy();
System.out.println("部署ID: " + deployment.getId());
System.out.println("部署名称: " + deployment.getName());
}
创建实例对象
@Autowired
RuntimeService runtimeService;
@Test
public void createProcesses(){
ProcessInstance studyCamunda = runtimeService.startProcessInstanceByKey("Process_0228vjo");
System.out.println("流程实例的ProcessInstanceId: " + studyCamunda.getId());
System.out.println("流程实例的ProcessDefinitionId: " + studyCamunda.getProcessDefinitionId());
}
再次打开控制台就可以发现你创建的流程实例
拾取任务,完成任务
那么流程示例怎么往下走呢
@Autowired
TaskService taskService;
@Test
public void tasksOfProcesses(){
// 获取ProcessInstance的列表
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
.processDefinitionKey("Process_0228vjo")
.active()
.list();
if (processInstanceList.isEmpty()){
throw new RuntimeException("没有流程实例!");
}
// 只获取一个流程实例进行(强制)拾取并完成操作
ProcessInstance processInstance = processInstanceList.get(0);
// 查询task
Task task = taskService.createTaskQuery()
.processInstanceId(processInstance.getId())
.active()
.singleResult();
// 强制拾取操作
//taskService.setAssignee(task.getId(),"user");
// 完成操作
if (task.getAssignee().equals("zhangsan"))
//完成任务---张三提交请假申请
taskService.complete(task.getId());
}
ok 目前的流程应该终于跑在到了经理的位置
网关
首先先声明网关虽然是一个节点 但是流程是不停留在网关节点上的,是网关的前面的节点拥有决策权
由于我在画图的时候,网关这一块的条件已经加上了,也就是flag这个字符串为‘true’往用户节点走,反之则往sendTask走
那么经理这个节点的代码实现就需要一个map
@Autowired
TaskService taskService;
@Test
public void tasksOfProcesses(){
// 获取ProcessInstance的列表
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
.processDefinitionKey("Process_0228vjo")
.active()
.list();
if (processInstanceList.isEmpty()){
throw new RuntimeException("没有流程实例!");
}
// 只获取一个流程实例进行(强制)拾取并完成操作
ProcessInstance processInstance = processInstanceList.get(0);
// 查询task
Task task = taskService.createTaskQuery()
.processInstanceId(processInstance.getId())
.active()
.singleResult();
if(task.getAssignee().equals('jack')){
// 完成操作
HashMap<String, Object> stringStringHashMap = new HashMap<>();
//经理的操作--同意或者不同意
stringStringHashMap.put("flag","true");
taskService.complete(task.getId(),stringStringHashMap);
}
}
流程来到了财务。。
SendTask
发送任务节点需要挂载到某一个java类
实现JavaDelegete接口节点一旦false 则会触发到execute方法
这里的.createMessageCorrelation(“message”)中配置了上面流程图中的Message Name填写字符串。
而.processInstanceBusinessKey(“messageBusinessKey”)中填写了一个特定的业务key,方便找到特定的Receive Task流程。
package org.example.email;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
public class SendEmail implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
ProcessEngineServices processEngineServices = delegateExecution.getProcessEngineServices();
//可以获取到RuntimeService
RuntimeService runtimeService = processEngineServices.getRuntimeService();
}
}
再来看一下DelegateExecution这个类内部的属性
/** execution Id */
String getId();
/** 流程实例id*/
String getProcessInstanceId();
/** 这个比较有用 主要就是start、end、take */
String getEventName();
/**
* 业务id,已经废弃的用法
*/
String getBusinessKey();
/**
* 业务id */
String getProcessBusinessKey();
/**
* 流程定义id
*/
String getProcessDefinitionId();
/**
* 获取父id,并发的时候有用
*/
String getParentId();
/**
* 获取当前的 Activityid
*/
String getCurrentActivityId();
/**
* 获取当前的 Activity name
*/
String getCurrentActivityName();
/**
* 获取TenantId 当有多个TenantId 有用
*/
String getTenantId();
/**
* 这个非常有用吧。当拿到EngineServices 对象所有的xxxService都可以拿到。
*/
EngineServices getEngineServices();
改一下上面经理同意的代码
@Autowired
TaskService taskService;
@Test
public void tasksOfProcesses(){
// 获取ProcessInstance的列表
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
.processDefinitionKey("Process_0228vjo")
.active()
.list();
if (processInstanceList.isEmpty()){
throw new RuntimeException("没有流程实例!");
}
// 只获取一个流程实例进行(强制)拾取并完成操作
ProcessInstance processInstance = processInstanceList.get(0);
// 查询task
Task task = taskService.createTaskQuery()
.processInstanceId(processInstance.getId())
.active()
.singleResult();
if(task.getAssignee().equals('jack')){
// 完成操作
HashMap<String, Object> stringStringHashMap = new HashMap<>();
//经理的操作--不同意
stringStringHashMap.put("flag","false");
taskService.complete(task.getId(),stringStringHashMap);
}
}
经理的节点走完会自动跳进SendTask execute方法,sendTask节点在流程中也是不停留的,execute执行完当前active的节点直接就到了它指向的节点
删除流程实例
@Test
public void deleteProcessInstance(){
List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery()
.processDefinitionKey("Process_0228vjo")
.active()
.list();
for (ProcessInstance processInstance : processInstanceList) {
//删除流程实例
runtimeService.deleteProcessInstance(processInstance.getProcessInstanceId(),"删除测试");
}
}
总结
接下来下面会说一下 参数在节点中的传递,监听等操作,以及更为复杂的bpmn流程图 佛系更新中