第十一节:Activiti6.0——定时器开始事件、消息开始事件和错误开始事件介绍
时间:2022-07-25
本文章向大家介绍第十一节:Activiti6.0——定时器开始事件、消息开始事件和错误开始事件介绍,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、概述
介绍: 在activiti中,事件按位置分可以有:开始事件、中间事件、边界时间、结束事件;按事件的特性区分有:捕获事件和抛出事件。除了事件,还有各种事件定义,常用的有:定时器事件定义、错误事件定义、信号事件定义、消息事件定义 、取消事件定义、补偿事件定义等。事件和事件定义可以进行组合,成为特定的事件。
此刻: 本文主要讲四种开始事件
- 无指定开始事件:不为开始事件指定任何的触发条件的事件。此处不介绍。
- 定时器开始事件:在开始事件中加入定时器事件定义。
- 消息开始事件:在开始事件中加入消息事件定义。
- 错误开始事件:错误开始事件只能使用在事件的子流程。
二、定时器开始事件
- 流程图
- 流程xml
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent">
<timerEventDefinition>
<!--从每分钟的0s开始,每隔5秒开始一次流程(生成一个流程实例)-->
<timeCycle>0/5 * * * * ?</timeCycle>
</timerEventDefinition>
</startEvent>
<userTask activiti:exclusive="true" id="UserTask" name="UserTask"/>
<endEvent id="_4" name="EndEvent"/>
<sequenceFlow id="_5" sourceRef="_2" targetRef="UserTask"/>
<sequenceFlow id="_6" sourceRef="UserTask" targetRef="_4"/>
</process>
- 编码部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
//部署流程后,不用我们自己启动流程实例,定时器的时间到了后会自动启动流程实例
Deployment deployment = repositoryService.createDeployment().addClasspathResource("timer-start-event.bpmn").deploy();
long count = runtimeService.createProcessInstanceQuery().count();
System.out.println("sleep前的流程实例个数:" + count);
//
//
//睡眠20s,5s运行一次,则会多4个流程实例
Thread.sleep(20 * 1000);
count = runtimeService.createProcessInstanceQuery().count();
System.out.println("sleep后的流程实例个数:" + count);
processEngine.close();
System.exit(0);
- 结果查看
- 个人遇到问题及猜测:在测试过程中遇到个数和时间不对。 定时开始事件设置的时间间隔为1s,31s后流程实例增加个数为3个,个人猜测:定时开始事件的流程实例启动间隔强制大于等于10s若设置的小于10s,则使用10s;若设置的时间间隔大于10s,则以设置的为准)
三、消息开始事件
- 流程图
- 流程xml
<message id="msg" name="msgName"></message>
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent">
<!--开始事件引用消息-->
<messageEventDefinition messageRef="msg"></messageEventDefinition>
</startEvent>
<userTask activiti:exclusive="true" id="UserTask" name="UserTask"/>
<endEvent id="_4" name="EndEvent"/>
<sequenceFlow id="_5" sourceRef="_2" targetRef="UserTask"/>
<sequenceFlow id="_6" sourceRef="UserTask" targetRef="_4"/>
</process>
- 编码部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("message-start-event.bpmn").deploy();
//通过消息启动流程实例,在一个项目中的消息事件会存储在表act_ru_event_subscr中,
// 并且因为流程实例依靠具体的消息来启动,因此在该项目中的消息需要唯一。例:如果一个流程的消息name定义为"msgName",第一次部署时act_ru_event_subscr
// 表会存储消息与部署的流程定义的关联,之后再部署相同的消息时,不会再增加记录,不会与消息绑定;即只有第一绑定消息的流程定义是有效的。
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("msgName");
System.out.println("流程实例ID:" + processInstance.getId());
processEngine.close();
System.exit(0);
4.结果查看:
运行结果:流程实例ID:345012
表act_ru_event_subscr:
四、错误开始事件
介绍: 此处模拟流程为,一个班级,班长清点人数,发现人数少了后,马上去报告班主任。
- 流程图
- 流程xml
<error id="errorId" errorCode="abc"></error>
<process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent"/>
<serviceTask activiti:exclusive="true" id="CountPeople" name="CountPeople"
activiti:class="com.xjf.test.delegate.CountPeopleDelegate"/>
<endEvent id="_4" name="EndEvent"/>
<sequenceFlow id="_5" sourceRef="_2" targetRef="CountPeople"/>
<sequenceFlow id="_6" sourceRef="CountPeople" targetRef="_4"/>
<!--triggeredByEvent配置必须为true,默认是false-->
<subProcess activiti:exclusive="true" id="_7" name="SubProcess" triggeredByEvent="true">
<startEvent id="_8" name="StartEvent">
<errorEventDefinition errorRef="errorId"></errorEventDefinition>
</startEvent>
<serviceTask activiti:exclusive="true" id="Report" name="Report"
activiti:class="com.xjf.test.delegate.ReportDelegate"/>
<endEvent id="_10" name="EndEvent"/>
<sequenceFlow id="_3" sourceRef="_8" targetRef="Report"/>
<sequenceFlow id="_11" sourceRef="Report" targetRef="_10"/>
</subProcess>
</process>
- ServiceTask的两个委托类
public class CountPeopleDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("清点人数,要抛出错误");
//抛出错误,子流程的错误开始事件会捕获
throw new BpmnError("abc");
}
}
public class ReportDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("少人了,准备上报");
}
}
- 编码发布
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("error-start-event.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
//流程实例启动后,会自动执行:主流程抛出错误,子流程捕获到错误然后一直执行完
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
System.out.println("流程实例id:" + processInstance.getId());
processEngine.close();
System.exit(0);
- 查看结果
五、总结
- 所有的开始事件都是捕获事件,都需要具体的动作或事件来触发。
- 错误开始事件不能独立存在,必须是其他事件的子流程。
- 边界事件:在BPMN2.0的事件分类中,边界事件被划分到中间事件中,BPMN2.0中将狭义的中间事件和边界事件,统称为中间事件。可以单独作为流程元素存在于流程中的事件为中间事件,而附属于某个流程元素(如任务、子流程等)的事件为边界事件。
- MySQL备份恢复第二篇(r5笔记第6天)
- SpringMVC 中配置 Swagger 插件.
- MySQL和Oracle对比学习之事务(r5笔记第4天)
- 【面试宝典】Java如何打印数组
- MySQL数据导入导出牛刀小试(r5笔记第3天)
- SpringMVC 异常处理.
- 一条简单的sql在11g和12c中的不同(r5笔记第2天)
- 浅析 SpringMVC 原理和配置.
- 使用impdp不当导致的数据丢失问题(r5笔记第1天)
- MySQL数据库 Event 定时执行任务.
- Tomcat 日志分割.
- crontab导致的频繁发送邮件的问题(r5笔记第20天)
- 再学习之Spring(依赖注入).
- 使用序列的问题ORA-02287(r5笔记第19天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android功耗优化(7)---如何分析wakelock(wakeup source)持锁问题
- 一道有意思的腾讯算法面试题
- 关于 JavaScript 错误处理的最完整指南(上半部)
- 排障集锦:九九八十一难之第十六难!-------------enoent ENOENT: no such file or directory, open ‘/root/package.json‘
- 大点干!早点散----------深入剖析GFS分布式文件系统
- 大点干!早点散----------ELK企业日志分析系统理论+实战!
- 面试题系列第8篇:谈谈String、StringBuffer、StringBuilder的区别?
- HTTP协议的请求与数据抓包
- Ubuntu 18.04 LTS 通过 Netplan 配置网络教程
- 【kafka源码】kafka内部的一些术语
- TKE使用自建NFS持久化存储
- 网站 SSL 检测 PCI DSS 不合规解决办法
- leetcode链表之分割链表
- 五分钟带你读懂 TCP全连接队列(图文并茂)
- Python基础