【activiti 入门】activiti6.0之事件总结

从结构上来讲如下图:

事件定义
    定时器事件定义
    错误事件定义
    信号事件定义
    消息事件定义
开始事件
    空开始事件
    定时开始事件
    消息开始事件
    信号开始事件
    错误开始事件
结束事件
    空结束事件
    错误结束事件
    取消结束事件
边界事件
    定时边界事件
    错误边界事件
    信号边界事件
    消息边界事件
    取消边界事件
    补偿边界事件
中间捕获事件
    定时中间捕获事件
    信号中间捕获事件
    消息中间捕获事件
内部触发(抛出)事件
    中间触发空事件
    信号中间触发事件
    补偿中间触发事件

从类型上分,应该算是6大类型吧,这是我个人的理解。

从操作方式上来看分三种:定义事件、捕获事件、抛出事件。

无论是什么事件,最终就是处理事情的。接下来挨个说:

事件定义 Event结尾的标签体
    定时器事件定义  类型Event Type类型为Time Event
    错误事件定义    -
    信号事件定义    类型Event Type类型为Signal Event
    消息事件定义    类型Event Type类型为Message Event
开始事件  StartEvent标签体
    空开始事件
    定时开始事件    类型Event Type类型为Time Event
    消息开始事件    类型Event Type类型为Message Event
    信号开始事件    -
    错误开始事件    类型Event Type类型为Erro Event
结束事件  EndEvent标签体
    空结束事件
    错误结束事件    类型Event Type类型为Erro Event
    取消结束事件    类型Event Type类型为Terminate Event
边界事件  BoundaryEvent标签体
    定时边界事件    类型Event Type类型为Time Event
    错误边界事件    类型Event Type类型为Erro Event
    信号边界事件    类型Event Type类型为Signal Event
    消息边界事件    类型Event Type类型为Message Event
    取消边界事件    -
    补偿边界事件    -
中间捕获事件 IntermediateCatchingEvent标签体
    定时中间捕获事件  类型Event Type类型为Time Event
    信号中间捕获事件  类型Event Type类型为Signal Event
    消息中间捕获事件  类型Event Type类型为Message Event
内部触发(抛出)事件  IntermediateThrowingEvent标签体
    中间触发空事件
    信号中间触发事件  类型Event Type类型为Signal Event
    补偿中间触发事件  -

这里每个事件都有其独特性,例如定时器事件可以指定定时方式,循环规则,信号抛出事件可以定义同步或者异步等。

需要注意的是,边界事件不能单独作为一个流程元素存在,必须依附于其他元素。

 

下面是相对官方的总结描述:

事件分类与事件定义

        BPMN2.0规定了多种的事件定义,这些事件定义被嵌套到不同的事件中,则可以成为不同类型的事件,这些事件具有不同的特性,并且BPMN2.0规定了这些事件允许出现的位置以及其作用,本小节将对BPMN2.0规范定义的事件进行分类。

按照事件的位置分类

        对事件按照位置进行分类,主要可分为开始事件、中间事件和结束事件,其中中间事件可以分为两类:单独作为流程节点的中间事件和依附在某个流程节点的中间事件,本书中所讲的中间事件是指单独作为流程节点的事件,依附在某个流程节点的中间事件,本书将称为边界事件,那么按照位置进行分类,本书将会有以下4种类型的流程事件:

  • 开始事件:表示流程开始的事件。
  • 结束事件:表示流程结束的事件。
  • 中间事件:出现在流程中,单独作为流程节点的事件。
  • 边界事件:附属于某个流程节点(如子流程、流程任务)的事件。

按照事件的特性分类

        按照事件的特性进行分类,可以将事件分为Catching事件和Throwing事件,Catching事件会一直等待被触发,而Throwing事件会自动触发并反馈结果,全部的开始事件是Catching事件,因为开始事件总会等待被触发,每种开始事件的触发条件不一样而已,例如定时器开始事件,就需要时间符合条件后触发。全部的结束事件是Throwing事件,结束事件会自动执行并返回结果。全部的边界事件是Catching事件,因为这些边界事件总会符合某些特定条件才会触发。部分的中间事件为Catching事件(如Signal Intermediate Catching Event),部分的中间事件为Throwing事件(如Signal Intermediate Throwing Event)。

事件定义概述

        事件主要用于体现Catching事件的触发和Throwing事件的结果,BPMN2.0规范中规定了多种事件定义:CancelEventDefinition、CompensationEventDefinition、ConditionalEventDefinition、ErrorEventDefinition、EscalationEventDefinition、MessageEventDefinition、LinkEventDefinition、SignalEventDefinition、TerminateEventDefinition和TimerEventDefinition。除此之外,还包括无指定事件和复合事件,无指定事件是指在一个事件中没有指定任何事件定义,复合事件是指在一个事件中包含多个事件定义。每个事件定义可以按照规定与事件(开始事件、结束事件和中间事件)结合,成为特定的事件。例如将TimerEventDefinition与开始事件结合,成为定时器开始事件。

定时器事件定义

        定时器事件是一个由定时器触发的事件,定时器事件的定义可以嵌套在开始事件、中间事件或者边界事件中。在流程文件中使用timerEventDefinition元素表示一个定时器事件定义,假设在一个开始事件中定义一个定时器事件定义,配置如下:

   <startEvent id="timerstartevent1" name="Timer start">
            <timerEventDefinition></timerEventDefinition>
        </startEvent>

只定义一个timerEventDefinition元素是不足以描述该定时器事件,需要往timerEventDefinition元素下加入子元素,timerEventDefinition下允许定义的子元素有以下3个:

  • timeDate:指定一个定时器触发的时间。
  • timeDuration:指定定时器激活后多久的时间内该定时器被运行。假设定时器在当前时刻激活,设置该值为PT5M,即会在5分钟后执行。
  • timeCycle:指定定时器的重复间隔,该元素常应用于一些定时任务的执行,包括流程的定时启动、任务提醒等。

        以上3个timerEventDefinition的子元素,在定义时间时,都需要遵守ISO 8601的国际标准,该标准是日期和时间的表示方法,其中timeCycle还支持使用cron表达式来设定定时器的重复间隔。代码清单11-1为timerEventDefinition的三个子元素的配置示例。

        代码清单11-1:

        codes\11\11.1\event-definition\resource\bpmn\timer\TimerDefine1.bpmn,

        codes\11\11.1\event-definition\resource\bpmn\timer\TimerDefine2.bpmn,

        codes\11\11.1\event-definition\resource\bpmn\timer\TimerDefine3.bpmn

 <timerEventDefinition>
                <timeDate>2018-10-10T06:00:00</timeDate>
            </timerEventDefinition>
            <timerEventDefinition>
                <timeDuration>PT5S</timeDuration>
            </timerEventDefinition>
            <timerEventDefinition>
                <timeCycle>R2/PT1M</timeCycle>
            </timerEventDefinition>

代码清单11-1中使用了timerEventDefinition的3个子元素进行配置,该3个配置均使用了ISO 8601格式的日期时间。ISO 8601标准中,如果需要同时表达日期和时间,需要在时间前加入大写字母T,如2018-10-10T06:00:00,表示2018年10月10日的6点0分0秒。如果需要表示一个时间段,可以加入大写字母P,例如P1D表示1天内,如果要表示某个时间段(精确到时间),则需要在时间前加入T,例如PT10M,即表示10分钟内。需要重复的时间,可以加入大写字母R,如本例的“R2/PT1M”表示执行2次,每次持续1分钟。元素timeCycle除了可以使用ISO 8601标准定义时间外,还可以使用cron表达式,cron表达式将在下一小节中讲解。

cron表达式

        一个cron表达式是一串由6到7个域组成并且以空格分隔的字段串,cron原来是UNIX的工具之一,主要用于进行任务调度,cron核心使用的就是cron表达式来处理任务调度,以下为一个简单的cron表达式:10 * * * * ?,表示每分钟的第10秒将会触发。

        一个完整的cron表达式总共有7个域(以空格分隔),从左到右表示秒、分、小时、月份中的日期、月份、星期中的日期和年份,其中年份域为可选项,例如有以下这个cron表达式:1 2 3 4 5 ? 2013,该表达式共有7个域,以空格隔开,该表达式表示2013年5月4日03时2分1秒,在该表达式中,第6个域(星期中的日期)使用了问号,表示并不需要关心该域,由于该表达式指定了第4个域(月份中的日期),因此此处使用问号,可以理解为不关心5月4日是星期几。以下为cron表达式中符号及其作用:

  • *:允许该域使用全部的值。假设在秒域值为10且分钟域为*,那么意味着每一分钟的第十秒将会符合表达式条件。
  • ?:只允许出现在第4个域(月份中的日期)和第6个域(星期中的日期),表示不关心该域的取值,由于两个域取值可能存在冲突,因此为不关心取值的域使用该符号。
  • -:该符号表示范围,假设将第3个域(小时)设置为10-12,则表示10点到12点。
  •  ,:该符号表示一个域内并列的多个值,例如第4个域(月份中的日期)值2,4,8,表示2号、4号和8号会触发。
  • /:使用该符号设置步长,假设将第1个域(秒)设置为5/15,表示从第5秒开始,步长为15,即第5、20、35、50秒时均会触发。
  • L:英文Last的缩写,如果出现在第4个域(月份中的日期),则为每个月的最后一天,如果出现第6个域(星期中的日期),则表示该星期的最后一天(周六),如果该符号出现在某个值后,如第6个域值为6L,则表示该月的最后一个星期5。
  • W:英文weekday的缩写,表示周一到周五(工作日),该符号只能出现在第4个域(月份中的日期)并且只能与其他值组合使用,如15W,则表示该月中与15号最接近的工作日。另外,L和W可以在第4个域中混合使用,表示该月的最后一个工作日。
  • #:该符号只能出现在第6个域(月份中的日期),表示该月的第几天,如果设值为#5,表示该月的第5天,如果设置为4#3,则前面的4表示星期中的日期,即4#3表示该月的第3个星期三(7是周6)。

        各个符号允许出现的域以及每个域的取值范围如下所示:

  • 秒:必选项,取值范围为0到59,允许出现的符号有“, - * /”。
  • 分钟:必选项,取值范围为0到59,允许出现的符号有“, - * /”。
  • 小时:必选项,取值范围为0到23,允许出现的符号有“, - * /”。
  • 月份中的日期:必选项,取值范围为1到31,允许出现的符号有“, - * ? / L W”。
  • 月份:必选项,取值范围为1-12或者月份的英文缩写,允许出现的符号有“, - * /”。
  • 星期中的日期:必选项,取值范围为1-7或者英文缩写,允许出现的符号有“, - * / L #”。
  • 年份:非必选项,取值范围为1970-2099,允许为空值,允许出现的符号有“, - * /”。

        假设现有一个检查工作日志的业务流程,需要在周一到周五下班时启动,那么创建定时器事件定义,并且使用timeCycle元素配合cron表达式进行时间定义:

 <timerEventDefinition>
                <timeCycle>* * 18 ? * 1,2,3,4,5</timeCycle>
            </timerEventDefinition>

  以上的cron表达式为“* * 18 ? 1,2,3,4,5”,表示周一到周五的18点将会触发。如果使用timeCycle元素定义周期性的任务,笔者觉得使用cron表达最为合适,即使cron表达式在刚接触时有点难理解,但是它强大的时间定义能力已经让众多的任务调度框架都对其提供支持,例如Quartz框架。

另外网上有在线设置测试的,可自行查找。

错误事件定义

        错误事件会被定义的错误信息所触发,BPMN中的错误事件主要用于处理流程中出现的业务异常。需要注意的是,流程中的业务异常与Java中的Exception是不同的概念,在设计业务时,如果满足一定的条件,那么就会触发错误事件。例如有一个检查服务器进程的业务流程,每隔6小时检查服务器的某个进程是否存在,如果该服务进程不存在,则触发原来定义好的错误事件,进入特定的处理流程。在BPMN2.0规范中,使用errorEventDefinition元素定义一个错误事件,配置如下所示:

<errorEventDefinition errorRef="errorRef"></errorEventDefinition>

     定义错误事件的errorEventDefinition元素下只有一个errorRef属性,errorRef引用定义的error元素id,一个errorEventDefinition可以不提供errorRef属性,表示定义了一没有实现的事件。代码清单11-2为error以及errorEventDefinition的配置。

        代码清单11-2:codes\11\11.2\event-definition\resource\bpmn\ErrorDefine.bpmn

 <error id="myError" errorCode="123"></error>
    <process id="testProcess" name="testProcess">
        <endEvent id="myErrorEndEvent">
            <errorEventDefinition errorRef="myError" />
        </endEvent>
    </process>

  在BPMN2.0规范中,规定了一个error元素需要包含以下属性:

  • id:该元素的唯一标识。
  • name:元素的名称,BPMN2.0规范中明确流程XML文件中需要支持该属性,Activiti并没有对其提供实现(允许在XML中配置,但是不会读取该属性)。
  • errorCdoe:错误事件编码,当处理业务时抛出相应的异常代码,流程引擎会根据该错误代码自动匹配到该error元素,定义error元素必须设定errorCode属性。
  • structureRef:结构引用属性,根据BPMN2.0规范,该属性用于引用公用的错误定义(引用itemDefinition),Activiti并不会读取该属性(配置了该属性,也不会产生效果)。

        错误事件定义可以被嵌套在开始事件(startEvent)、边界事件(boundaryEvent)和结束事件(endEvent)中成为错误开始事件、错误边界事件和错误结束事件。

信号事件定义

        在讲解第9章流程控制时,就已经使用过信号事件定义,信号事件是一种引用了信号定义的事件,可以使用一个信号向全部的流程发送广播(前提是流程定义使用了同样名称的信号)。定义一个信号事件,需要使用signalEventDefinition元素,与错误事件一样,当使用了signalEventDefinition元素定义一件信号事件时,需要使用signalRef属性来引用一个信号元素(signal),signalRef的值需要为signal的id,信号事件的XML配置如以下代码所示:

        代码清单11-3:codes\11\11.2\event-definition\resource\bpmn\SignalDefine.bpmn

 <signal id="signalA" name="signalA"></signal>
    <process id="testProcess" name="testProcess">
        ...
            <signalEventDefinition signalRef="signalA"></signalEventDefinition>
        ...
    </process>

  在BPMN2.0规范中,一个信号元素(signal)允许有以下3个属性:

  • id:该元素的唯一标识,必须提供。
  • name:signal元素的名称,必须提供,否则Activiti在解析流程文件时将会抛出异常,信息为“signal with id XXX has no name”异常。另外,在一个流程定义中,不允许同时出现多个name相同的signal元素,否则将抛出异常,信息为“duplicate signal name XXX”。
  • structureRef:该属性与错误事件的structureRef属性一样,BPMN2.0规范中规定了该属性引用公用的配置,Activiti并没有读取和使用该属性。

        信号事件可以嵌套在边界事件、中间Catching事件和中间Throwing事件中成为信号边界事件、信号中间Catching事件和信号中间Throwing事件,其中信号边界事件和信号中间Catching事件是Catching事件,即这些事件会一直等待信号,接收到信号后事件才会被触发,如果执行流到达这些Catching事件,Activiti会在ACT_RU_EVENT_SUBSCR表中加入相应的事件描述数据。

消息事件定义

        消息事件是一种引用了消息定义的事件,与信号不同的是,消息只能指向一个接收人,而不能像信号一样进行广播。使用messageEventDefinition元素定义一个消息,使用messageRef属性引用一个消息(引用消息元素的id)。在BPMN2.0规范中,messageEventDefinition下还有一个operationRef的子元素,用于在可执行的流程中定义消息事件的具体操作,但是Activiti人实现中并没有使用该operationRef元素。代码清单11-4为消息事件的XML配置。

        代码清单11-4:codes\11\11.2\event-definition\resource\bpmn\MessageDefine.bpmn

  <message id="myMsg" name="myMsg"></message>

    <process id="medProcess" name="medProcess">
        ...
            <messageEventDefinition messageRef="myMsg"></messageEventDefinition>
        ...
    </process>

   定义一个消息元素使用message元素,该元素包含以下属性:

  • id:该元素的唯一标识。
  • name:消息的名称,使用RuntimeService的messageEventReceived方法时传入该参数,可选项。
  • itemRef:用于指定该消息引用的itemDefinition元素。

        消息事件可以嵌套在开始事件和中间Catching事件中成为消息开始事件和消息中间Catching事件。其中消息开始事件可以通过RuntimeService的startProcessByKey方法启动流程,如果执行流遇到消息中间Catching事件时,会停留在该流程节点前,一直等待消息的来临,一旦接收到消息,流程才会继续向前执行。

取消事件定义

        在BPMN2.0规范中,取消事件使用在事务子流程(Transaction Sub-Process)模型中,取消事件定义可以使用在边界事件和结束事件中,成为取消边界事件(Cancel Boundary Event)和取消结束事件(Cancel End Event)。以下代码使用cancelEventDefinition元素定义一个取消事件:

<cancelEventDefinition></cancelEventDefinition>

  取消边界事件是Catching事件,会等待被触发,而取消结束事件则为Throwing事件。关于取消边界事件和取消结束事件的作用以及其应用,请参看11.4.3章节。

补偿事件定义

        补偿机制主要用于对已经成功完成的流程作回退处理,因为这些流程的结果有可能不是所期望的,并且希望能将其回退。如果当前的流程活动是激活状态的,那么不能使用补偿机制,但可以考虑使用取消机制,相反,取消有可能会导致补偿的触发,例如在子流程中。

        补偿事件主要用于触发或者处理补偿机制,BPMN2.0规定了补偿事件定义可以嵌套在开始事件、中间Catching事件、中间Throwing事件和结束事件。如果将补偿事件定义使用在中间Catching事件时,不允许作为单独的流程节点,因此如果嵌套在中间Catching事件时,将成为补偿边界事件。使用compensateEventDefinition元素定义一个补偿事件:

<compensateEventDefinition><compensateEventDefinition/>

 该元素除了id属性外,还有waitForCompletion属性,根据BPMN2.0规范,该属性决定抛出的事件是否等待补偿完成,当前版本的Activiti不支持该属性。另外,compensateEventDefinition元素还有一个activityRef属性,如果在中间补偿事件的定义中设置该属性,则补偿的触发就会有针对性,该补偿会只针对指定的已经完成的流程活动,如果不指定该属性,那么补偿将会产生广播的效果,即会触发全部的(符合条件的)补偿事件。

        Activiti目前只对补偿边界事件和补偿中间Throwing事件作了实现,相应请见边界事件和中间Throwing事件章节。

其他事件定义

        除了以上的事件定义外,BPMN2.0还有如下事件定义:条件事件定义(ConditionalEventDefinition)、升级事件定义(EscalationEventDefinition)、连接事件定义(LinkEventDefinition)和终止事件定义(TerminateEventDefinition),目前版本除了终止事件定义外,其余事件还没有提供实现。以下代码片断定义了一个终止事件定义:

<terminateEventDefinition activiti:terminateAll="true"></terminateEventDefinition>

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能吃辣的JAVA程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值