首页 > 其他分享 >activiti中的事件

activiti中的事件

时间:2023-07-02 20:56:00浏览次数:43  
标签:定时器 结束 错误 activiti 取消 流程 事件

activiti中常见的事件按事件可以出现的位置可以分为 开始事件、结束事件、边界事件、中间事件。

按事件的类型分可以分为信号事件、消息事件、error事件,定时器事件

按照事件的特性可以分为Catching事件和Throwing事件,Catching会一直等待被触发,Throwing事件会自动触发并反馈结果,全部的开始事件都是Catching事件,全部的结束事件都是Throwing事件,结束事件会自动执行并返回结果。

一、开始事件

1.1 无指定开始事件

最常用的流程开始事件,有这种开始事件的流程需要使用RutimeService来启动。

1.2 定时器开始事件

把定时器事件放在开始的位置,用于定时的启动流程,有这种开始事件的流程不需要用api来启动。

<startEvent id="sid-EF961064-FBCE-4FDF-B855-DFDC50A70E06">
      <timerEventDefinition></timerEventDefinition>
</startEvent>

如上,定时器开始事件像这样定义,触发的时间需要在timerEventDefinition中加入子元素来指定,

timeDate: 指定一个定时器触发的时间,如2023-06-01T06:00:00

timeDuration: 指定定时器被激活后多久会执行,假如当前时刻被激活,设置该值为PT5M,表示5分钟后会执行。

timeCycle: 指定定时器重复执行的间隔,设置这个值后定时器会每隔一段时间就重复执行一次,

该配置支持cron表达式

上边这个流程使用了定时器开始事件,并指定了timeDate,部署此流程文件后到达指定时间时就会自动启动此流程。

<startEvent id="sid-EF961064-FBCE-4FDF-B855-DFDC50A70E06">
      <timerEventDefinition>
        <timeDate>2023-06-18T21:09:00</timeDate>
      </timerEventDefinition>
</startEvent>

1.3 消息开始事件

为开始事件加入消息事件的定义,这种流程需要使用RuntimeService.startProcessByMessage方法启动。

// 注意入参要使用messageName
ProcessInstance startProcessInstanceByMessage(String messageName);

需要在流程文件中先定义message,然后在消息事件定义中引用定义的消息

上边这个流程中使用了消息开始事件,部分流程文件如下,注意一开始先定义了消息

 <message id="myMessage" name="myMessage"></message>
  <process id="process" isExecutable="true">
    <startEvent id="sid-4C60A445-5925-40CE-9AFB-E72E7A341E82">
      <messageEventDefinition messageRef="myMessage"></messageEventDefinition>
    </startEvent>
    <userTask id="userTask1" name="message start task"></userTask>
    <sequenceFlow id="sid-0F009245-57A2-4F15-9B79-F86521C03A4E" sourceRef="sid-4C60A445-5925-40CE-9AFB-E72E7A341E82" targetRef="userTask1"></sequenceFlow>
    <endEvent id="sid-A5DE705E-23BF-4D29-A5A1-5BF93F0341F2"></endEvent>
    <sequenceFlow id="sid-B4BEA749-046C-4AA6-9413-416881C52E80" sourceRef="userTask1" targetRef="sid-A5DE705E-23BF-4D29-A5A1-5BF93F0341F2"></sequenceFlow>
  </process>

1.4 错误开始事件

错误开始事件只能在事件子流程中使用。

上边这个流程图,上半部分是一个主流程,它有一个serviceTask关联了一个java类,在java类中会抛出BpmnError。下半部分是一个事件子流程,它有个错误开始事件,当捕获到主流程抛出的错误时就会启动子流程。

service task关联的java类

public class ThrowErrorServiceTask implements JavaDelegate {

    public void execute(DelegateExecution execution) throws Exception {
        System.out.println("抛出error");
        //构造方法的参数是errorCode
        throw new BpmnError("testError");
    }
}

整个流程的流程文件

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
   <!-- error定义 -->
  <error id="testError" errorCode="testError"></error>
  <process id="errorStartTest" name="errorStartTest" isExecutable="true">
    <startEvent id="sid-F856CED3-6AE3-4F88-BC43-0E9DAB2B016B"></startEvent>
    <serviceTask id="sid-AC5D1738-EF21-4126-B92E-1CA34A9E62B0" name="throw error" activiti:class="com.lyy.serviceTask.ThrowErrorServiceTask"></serviceTask>
    <sequenceFlow id="sid-24A60E23-D939-44BF-8433-1C8DACAD3197" sourceRef="sid-F856CED3-6AE3-4F88-BC43-0E9DAB2B016B" targetRef="sid-AC5D1738-EF21-4126-B92E-1CA34A9E62B0"></sequenceFlow>
    <endEvent id="sid-57EA43F4-D87D-48E5-8240-6B729F03DDF1"></endEvent>
    <sequenceFlow id="sid-07A2F280-19B5-43D4-8319-015A9C806040" sourceRef="sid-AC5D1738-EF21-4126-B92E-1CA34A9E62B0" targetRef="sid-57EA43F4-D87D-48E5-8240-6B729F03DDF1"></sequenceFlow>
    <subProcess id="errorDealSubProcess" name="subProcess" triggeredByEvent="true">
      <startEvent id="sid-D66367D7-6F71-480B-9E18-85758C3D1166">
         <!-- 错误事件定义,引用testError这个error -->
        <errorEventDefinition errorRef="testError"></errorEventDefinition>
      </startEvent>
      <userTask id="sid-B3A07EC3-1F53-4D8B-AEB6-CD859FFD9A6E" name="error task" activiti:assignee="kermit"></userTask>
      <endEvent id="sid-ACF84D26-3842-434B-8E32-641F248864BC"></endEvent>
      <sequenceFlow id="sid-5EC3D575-386D-4505-B383-AF4831F752E5" sourceRef="sid-D66367D7-6F71-480B-9E18-85758C3D1166" targetRef="sid-B3A07EC3-1F53-4D8B-AEB6-CD859FFD9A6E"></sequenceFlow>
      <sequenceFlow id="sid-B6D6FB29-5DF6-4585-A588-5C9535F39945" sourceRef="sid-B3A07EC3-1F53-4D8B-AEB6-CD859FFD9A6E" targetRef="sid-ACF84D26-3842-434B-8E32-641F248864BC"></sequenceFlow>
    </subProcess>
  </process>
</definitions>

在serviceTask中抛出bpmn异常就会触发事件子流程中的错误开始事件。如果指定了errorRef就只会监听对应的errorCode,如果不指定errorRef所有的BpmnError都会触发此错误开始事件。

注意error只在当前流程的范围内有效,流程A里边抛出的error不会被流程B捕获到。

二、结束事件

结束事件都是抛出事件,这些事件会自动执行并反馈结果。使用endEvent元素定义结束事件。

2.1 无指定结束事件

流程在结束时不会进行任何额外的操作。

2.2 错误结束事件

当执行流到达错误结束事件时会结束该执行流并且抛出错误,该错误可以被"错误边界事件"捕获,如果没有定义任何的错误边界事件当前这个错误结束事件就会被当作无指定错误事件执行,因此错误结束事件一般在子流程中使用。

上边这个流程启动后会到达一个嵌套子流程,在子流程内部sub task任务完成后经过排他网关后有两个分支,网关出口的两条线上添加了 ${days<5} 和${days>=5} 的条件,当流程变量days<5时子流程正常结束,主流程到达endTask,当days>=5时子流程到达错误结束事件抛出错误,这个流程中定义抛出的errorRef是subError,

然后子流程边界上定义了错误边界事件,引用的也是subError,所以会捕获抛出的异常然后流程到达error task

在启动流程时需要传入流程变量

RuntimeService runtimeService = applicationContext.getBean(RuntimeService.class);
Map<String,Object> map = new HashMap<String, Object>();
map.put("days",4);
runtimeService.startProcessInstanceByKey("errorEndEvent",map);
runtimeService.deleteProcessInstance("91574","test");

完整的流程文件

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <!-- 错误定义 -->
  <error id="subError" errorCode="subError"></error>
  <process id="errorEndEvent" isExecutable="true">
    <startEvent id="sid-B5DB263B-B85B-468E-AD7D-69931BF84027"></startEvent>
    <subProcess id="sid-8FE783C6-0078-4451-80F0-F0A5ECB9B0E1" name="subProcess">
      <startEvent id="sid-EE6B144F-A942-4E8C-AACD-B306F77CAEF4"></startEvent>
      <userTask id="subTask" name="sub task"></userTask>
      <exclusiveGateway id="sid-0CD31408-A9AA-4A65-B5D1-7B56B7EB492D"></exclusiveGateway>
      <endEvent id="sid-39D597D9-1356-4A06-BDE1-612E623CD5CD"></endEvent>
        <!-- 错误结束事件 -->
      <endEvent id="sid-A70F88EC-FA1C-4216-8332-9C015735C20C">
        <errorEventDefinition errorRef="subError"></errorEventDefinition>
      </endEvent>
      <sequenceFlow id="sid-A83781E7-B0EA-4428-A4E7-A43E1A346D5B" sourceRef="sid-EE6B144F-A942-4E8C-AACD-B306F77CAEF4" targetRef="subTask"></sequenceFlow>
      <sequenceFlow id="sid-130DE08E-8B56-4A09-8001-8703C38BF3F7" sourceRef="subTask" targetRef="sid-0CD31408-A9AA-4A65-B5D1-7B56B7EB492D"></sequenceFlow>
      <sequenceFlow id="sid-D8DD81EA-7C81-44E1-A55F-780460AFBAEB" sourceRef="sid-0CD31408-A9AA-4A65-B5D1-7B56B7EB492D" targetRef="sid-39D597D9-1356-4A06-BDE1-612E623CD5CD">
        <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days<5}]]></conditionExpression>
      </sequenceFlow>
      <sequenceFlow id="sid-7A76813A-7811-4285-BD7C-E21D04B61157" sourceRef="sid-0CD31408-A9AA-4A65-B5D1-7B56B7EB492D" targetRef="sid-A70F88EC-FA1C-4216-8332-9C015735C20C">
        <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days>=5}]]></conditionExpression>
      </sequenceFlow>
    </subProcess>
    <userTask id="endTask" name="endTask"></userTask>
    <sequenceFlow id="sid-4F53CCE3-D1CE-49CA-88D8-7F8765F8689E" sourceRef="sid-8FE783C6-0078-4451-80F0-F0A5ECB9B0E1" targetRef="endTask"></sequenceFlow>
    <endEvent id="sid-8CE1BAED-26F0-45C1-8F6A-312630401E25"></endEvent>
    <sequenceFlow id="sid-6E81D5EC-E7EF-4812-8F81-571BB0EAD2F4" sourceRef="endTask" targetRef="sid-8CE1BAED-26F0-45C1-8F6A-312630401E25"></sequenceFlow>
    <!-- 错误边界事件 -->
    <boundaryEvent id="sid-627F3E39-464C-4AD1-B269-F5B588C53894" attachedToRef="sid-8FE783C6-0078-4451-80F0-F0A5ECB9B0E1">
      <errorEventDefinition errorRef="subError"></errorEventDefinition>
    </boundaryEvent>
    <userTask id="errorTask" name="error task"></userTask>
    <sequenceFlow id="sid-9FF79957-5F09-48F1-9C15-D461FC8F8593" sourceRef="sid-627F3E39-464C-4AD1-B269-F5B588C53894" targetRef="errorTask"></sequenceFlow>
    <endEvent id="sid-672DDBF7-8025-4EEF-B15B-1BE9401C6929"></endEvent>
    <sequenceFlow id="sid-E6E71E95-DB6F-4ED4-9130-2FABC5E6F609" sourceRef="errorTask" targetRef="sid-672DDBF7-8025-4EEF-B15B-1BE9401C6929"></sequenceFlow>
    <sequenceFlow id="sid-8C67E741-D0F0-42FE-84FB-9D5298ED9376" sourceRef="sid-B5DB263B-B85B-468E-AD7D-69931BF84027" targetRef="sid-8FE783C6-0078-4451-80F0-F0A5ECB9B0E1"></sequenceFlow>
  </process>
</definitions>

2.3 取消结束事件和取消边界事件

取消结束事件只能在事务子流程中使用,一般会和取消边界事件配合使用,取消结束事件会触发依附在事务子流程边界上的取消边界事件。取消结束事件的触发会触发补偿机制。

当取消边界事件被触发时会将当前的流程中断,然后同步的执行补偿机制。取消边界事件在离开事务子流程前会一直等待所有补偿任务的结束,当补偿任务结束后执行流会从取消边界事件离开子流程。

下面有一个汇款流程,汇款流程作为一个事务子流程在主流程中使用,当汇款完成后需要用户进行最终确认,如果用户确认则正常结束流程,否则触发取消结束事件并进行补偿操作。

其中的汇款操作,取消汇款,接收取消都是简单的打印一句话

取消结束事件就会触发取消汇款这个补偿,补偿完成后会到达取消边界事件

完整的流程图

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="cancelEndEvent1" isExecutable="true">
    <transaction id="eventSub" name="subProcess">
      <startEvent id="sid-8BC8D0D3-4919-4C4B-92D1-89482A047D6A"></startEvent>
      <serviceTask id="huiKuan" name="汇款操作222" activiti:class="com.lyy.serviceTask.HuiKuanService"></serviceTask>
      <exclusiveGateway id="sid-056E07FA-4CEE-4CC9-ACD4-E3716FAEF48C"></exclusiveGateway>
      <endEvent id="sid-22A5F886-CDBD-47F0-B17A-A1A6E236E63A"></endEvent>
      <endEvent id="sid-B82F2759-AF61-46DB-98DF-9CD1EC0F678E">
        <cancelEventDefinition></cancelEventDefinition>
      </endEvent>
      <boundaryEvent id="sid-7003DABD-72C5-4570-9F28-717590290F0F" attachedToRef="huiKuan" cancelActivity="true">
        <compensateEventDefinition></compensateEventDefinition>
      </boundaryEvent>
      <serviceTask id="cancelHuiKuan" name="取消汇款" activiti:class="com.lyy.serviceTask.CancelHuiKuan" isForCompensation="true"></serviceTask>
      <userTask id="confirm" name="确认汇款"></userTask>
      <sequenceFlow id="sid-2298D967-FD3F-4F98-B959-721F8A1643DC" sourceRef="sid-8BC8D0D3-4919-4C4B-92D1-89482A047D6A" targetRef="huiKuan"></sequenceFlow>
      <sequenceFlow id="sid-5376EBB8-A8DC-4561-960C-AF61F6ED09F2" sourceRef="huiKuan" targetRef="confirm"></sequenceFlow>
      <sequenceFlow id="sid-258E4C3C-73E0-4EFA-8A69-01E40F4E36FF" sourceRef="confirm" targetRef="sid-056E07FA-4CEE-4CC9-ACD4-E3716FAEF48C"></sequenceFlow>
      <sequenceFlow id="sid-91FB9340-201D-4324-90FB-A11970667985" sourceRef="sid-056E07FA-4CEE-4CC9-ACD4-E3716FAEF48C" targetRef="sid-B82F2759-AF61-46DB-98DF-9CD1EC0F678E">
        <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag==false}]]></conditionExpression>
      </sequenceFlow>
      <sequenceFlow id="sid-F42022BA-F52B-44A5-8934-B6C1697BB2F4" sourceRef="sid-056E07FA-4CEE-4CC9-ACD4-E3716FAEF48C" targetRef="sid-22A5F886-CDBD-47F0-B17A-A1A6E236E63A">
        <conditionExpression xsi:type="tFormalExpression"><![CDATA[${flag==true}]]></conditionExpression>
      </sequenceFlow>
    </transaction>
    <startEvent id="sid-FBF27FA9-358F-4921-BE80-4A1C41B3E2E7"></startEvent>
    <boundaryEvent id="sid-973FE65A-C0AE-4072-AA92-83ED2CB42C6C" attachedToRef="eventSub" cancelActivity="false">
      <cancelEventDefinition></cancelEventDefinition>
    </boundaryEvent>
    <serviceTask id="receiveCancel" name="接收取消操作" activiti:class="com.lyy.serviceTask.ReceiveCancel"></serviceTask>
    <sequenceFlow id="sid-C552E510-5FDF-41B6-B6A0-4EF7C6878234" sourceRef="sid-973FE65A-C0AE-4072-AA92-83ED2CB42C6C" targetRef="receiveCancel"></sequenceFlow>
    <sequenceFlow id="sid-82B61457-A6F7-4EE5-821B-60BBFADD3636" sourceRef="sid-FBF27FA9-358F-4921-BE80-4A1C41B3E2E7" targetRef="eventSub"></sequenceFlow>
    <endEvent id="sid-6DDB28A5-C577-4814-9D1E-AFD886E0B702"></endEvent>
    <sequenceFlow id="sid-EC15EB6D-9F73-4CC2-B70B-71069B513DFF" sourceRef="eventSub" targetRef="sid-6DDB28A5-C577-4814-9D1E-AFD886E0B702"></sequenceFlow>
    <association id="sid-D58DDE81-5384-43AF-9A16-FA3889A80DB5" sourceRef="sid-7003DABD-72C5-4570-9F28-717590290F0F" targetRef="cancelHuiKuan" associationDirection="None"></association>
  </process>
</definitions>

标签:定时器,结束,错误,activiti,取消,流程,事件
From: https://www.cnblogs.com/chengxuxiaoyuan/p/17521371.html

相关文章

  • c#学习笔记---------------------事件
    一、事件的原理事件(Event)定义:类 或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。在典型的C#Windows窗体或Web应用程序中,可订阅由按钮和列表框等控件引发的事件。可以使用VisualC#集成开......
  • laytpl( Layui 的一款轻量 JavaScript 模板引擎)html标签点击事件传递多参
     <scripttype="text/html"id="aobjectvalue_temp"><spanclass="us-font-blue"style="cursor:pointer"onclick="seeinfo('{{d.aobjectkey}}','{{d.atype}}')">[资源详情]</spa......
  • jquery的几种常见事件
    1.事件ready(fn)当DOM(文档对象模型)已经加载,并且页面(包括图像)已经完全呈现时,会发生ready事件。通俗的来讲就是当页面加载完时就会执行此函数事件。可以在同一个页面中无限次地使用$(document).ready()事件。其中注册的函数会按照(代码中的)先后顺序依次执行。$(document).read......
  • ABP - 本地事件总线
    1.事件总线在我们的一个应用中,经常会出现一个逻辑执行之后要跟随执行另一个逻辑的情况,例如一个用户创建了后续还需要发送邮件进行通知,或者需要初始化相应的权限等。面对这样的情况,我们当然可以顺序进行相应的逻辑代码的编写,但这样会导致各种业务逻辑全部集中耦合在一个类中,违背......
  • elecrton 自定义关闭事件
     main.jsconst{app,BrowserWindow,Menu,ipcMain}=require('electron')constmainWindow=newBrowserWindow({webPreferences:{contextIsolation:false//必须有,不然报错}})//执行关闭自定义关闭ipcMain.on('handelClose'......
  • el-tree需要自定义双击事件触发选择节点
    单击事件onclick="xxxx"双击事件ondblclick="xxxx"<el-tree:data="data"@node-click="handleNodeClick"></el-tree>data(){return{numTime:0,}},methods:{//自定义双击事件handleNodeClick(......
  • Android ListView的事件监听
    1、数据项点击事件,针对的是ListView每个数据项的点击事件listView.setOnItemClickListener{_,_,position,_->Toast.makeText(this,"position:$position",Toast.LENGTH_LONG).show()}2、ListView组件焦点事件(不是指单个item,是整个ListView)listView.setOnFocusCh......
  • 高德地图动态Marker和自定义弹框、交互事件、中心点跳转
    高德地图vue3使用下载NPM:npmi@amap/amap-jsapi-loader--save根据官网提示,VUE3需要改变监听模式下载npmi@vue/reactivity组件内配置初始化<scriptsetup>//开发技术vue3piniatsimport{ref}from"vue";importAMapLoaderfrom"@amap/amap-jsapi-loa......
  • Activiti、Flowable和Camunda选型和对比
    选型的几个标准:社区活跃,至少在Github上能排上名的至少支持BPMN2协议的免费、开源根据上面的标准,目前几大工作流引擎就只有Activiti、Flowable和Camunda了,有些人会问为什么没有AirFlow相关的呢?很明显,AirFlow属于编排类流程引擎,跟工作流没太大关系,他们的共同点就是流程控......
  • ABP VNext事件总线-本地事件
    1、本地事件分为发布事件和订阅事件,其中,发布事件和订阅事件都必须要注册到ID中,使用接口ITransientDependency来注册,方便让事件总线发现并注册他们。2、发布事件需要使用ID获取ILocalEventBus服务,在定义一个发布方法之后,使用该服务的PublishAsync()方法来发布事件//定义一......