2023年11月29日发(作者:)
Activiti(四)--流程事件
1 事件分类
1.1 按照事件的位置分类
开始事件:表⽰流程开始的事件
结束事件:表⽰流程结束的事件
中间事件:出现在流程中,单独作为流程节点的事件
1.2 按照事件的特性分类
Catching事件:会⼀直等待被触发
Throwing事件:会⾃动触发并反馈结果
2.事件定义
2.1 定时器事件定义
定时器事件是由定时器触发的事件,定时器事件的定义可以嵌套在开始事件,中间事件或者边界事件中.配置如下:
<timerEventDefinition>
<timeDate>2018-10-10T06:00:00timeDate>
timerEventDefinition>
<timerEventDefinition>
<timeDuration>PT5StimeDuration>
timerEventDefinition>
<timerEventDefinition>
<timeCycle>R2/PT1MtimeCycle>
timerEventDefinition>
以上三个timerEventDefinition的⼦元素,在定义时间时,都需要遵守ISO 8601的国际标准,该标准是关于⽇期和时间的表⽰⽅法的标准,其中
timeCycle还⽀持使⽤cron表达式来设定定时器的重复间隔.
2.2 错误事件定义
错误事件会被定义的错误信息所触发,BPMN中的错误事件主要⽤于处理流程中出现的业务异常.流程中的业务异常与Java中的Exception是
不同的概念,在设计业务时,如果满⾜⼀定的条件,那么就会触发错误事件.
<error id="myError" errorCode="123">error>
<process id="testProcess" name="testProcess">
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError"/>
endEvent>
process>
BPMN规范规定⼀个error元素需要包含以下属性
id:该元素的唯⼀标识
name:元素的名称
errorCode:错误事件编码,当处理业务时抛出相应的异常代码,流程引擎会根据该错误代码⾃动匹配到该error元素,定义error元素必须设定
errorCode属性
structureRef:结构引⽤属性
2.3 信号事件定义
信号事件是⼀种引⽤了信号定义的事件,可以使⽤⼀个信号向全部的流程发送⼴播(前提是流程定义使⽤了同样名称的信号),信号事件的xml配
置如下:
<signal id="signalA" name="signalA">signal>
<process id="testProcess" name="testProcess">
...
<signalEventDefintion signalRef="signalA">signalEventDefinition>
...
process>
id:该元素的唯⼀标识,必须提供
name:signal元素的名称,必须提供,否则Activiti在解析流程⽂件时会抛出异常,在⼀个流程定义中,不允许同时出现多个name相同的signal元
素,否则将抛出异常
structureRef:该属性与错误事件的structureRef属性⼀样
2.4 消息事件定义
消息事件是⼀种引⽤了消息定义的事件,与信号不同的是,消息只能指向⼀个接收⼈,⽽不能像信号⼀样进⾏⼴播.使⽤messageRef属性引⽤⼀
个消息(引⽤消息元素的id);
<message id="myMsg" name="myMsg">message>
<process id="medProcess" name="medProcess">
...
<messageEventDefinition messageRef="myMsg">messageEventDefinition>
...
process>
id:该元素的唯⼀标识
name:消息的名称,使⽤RuntimeService的messageEventReceived⽅法时传⼊该参数
itemRef:⽤于指定该消息引⽤的itemDefinition元素
2.5 取消事件定义
取消事件使⽤在事务⼦流程(Transaction Sub-Process)模型中,取消事件定义可以使⽤在边界事件和结束事件中,称为取消边界事件和取消
结束时间
<cancelEventDefinition>cancelEventDefinition>
2.6 补偿事件定义
补偿机制主要⽤于对已经成功完成的流程做回退处理,因为这些流程的结果吗有可能不是我们所期望的,如果当前流程活动时激活状态的,那么
不能使⽤补偿机制,但是可以考虑取消机制,相反,取消友可能会导致补偿的触发.
<compensateEventDefinition><compensateEventDefinition/>
3 开始事件
3.1 ⽆指定开始事件
没有为其指定任务触发条件的开始事件为⽆指定开始事件,使⽤⽆指定开始事件,流程引擎并不知道流程将会在什么时候开始,如果需要启动流
程,就必须使⽤RuntimeService的startProcessByXXX⽅法.
<process id="timerStartProcess" name="timerStartProcess">
<startEvent id="startEvent1" name="start">startEvent>
<userTask id="userTask1" name="task">userTask>
<endEvent id="endEvent1" name="End">endEvent>
<sequenceFlow id="flow1" name="" sourceRef="startEvent1" targetRef="userTask1">sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="userTask1" targetRef="endEvent1">sequenceFlow>
process>
3.2 定时器开始事件
在开始事件中加⼊定时器事件定义,该开始事件就成为⼀个定时器开始事件,当时符合条件,流程启动,⽽并不需要像⽆指定开始事件⼀样,使⽤
API启动流程
<process id="timerStartProcess" name="timerStartProcess">
<startEvent id="timerstartevent1" name="Timer start">
<timerEventDefinition>
<timeCycle>0/5 * * * * ?timeCycle>
timerEventDefinition>
startEvent>
<userTask id="userTask1" name="check log">userTask>
<endEvent id="endEvent1" name="end">endEvent>
<sequenceFlow id="flow1" name="" sourceRef="timerstartevent1" targetRef="userTask1">sequence>
<sequenceFlow id="flow2" name="" sorrceRef="usertask1" targetRef="endevent1">sequenceFlow>
process>
3.3 消息开始事件
为开始事件加⼊消息事件的定义可以使其成为消息开始事件,此时可以使⽤RuntimeService的startProcessByMessage⽅法启动流程
<message id="msgA">message>
<process id="myProcess" name="myProcess">
<userTask id="userTask1" name="myTask">userTask>
<endTask id="endevent1" name="End">endEvent>
<startEvent id="messagestartevent1" name="Message start">
<messageEventDefintion messageRef="msgA">messageEventDefinition>
startEvent>
<sequenceFlow id="flow1" name="" sourceRef="messagestartevent1" targetRef="userTask1">sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="userTask1" targetRef="endevent1">sequenceFlow>
process>
//
部署流程⽂件
repositoryService.createDeployment().addClasspathResource("bpmn/").deploy();
//
启动流程
runtimeService.startProcessInstanceByMessage("msgA");
//
查询流程
runtimeService.createProcessInstanceQuery().count();
3.4 错误开始事件
错误开始事件只能在事件⼦流程中使⽤,该事件不能在其他的流程中使⽤,包括最⾼级流程(Top-Level Process),嵌套⼦流程(Sub-Process)
和调⽤⼦流程(Call Activity).
假设当前有⼀个检查服务器8080端⼝的流程,当流程启动后,会检查服务器的8080端⼝是否存在,如果不存在,则执⾏事件⼦流程,对应的流程
图和代码如下:
<error id="" errorCode="error">error>
<Process id="errorStartProcess" name="errorStartProcess">
<startEvent id="startEvent1" name="Start">startEvent>
<subProcess id="eventProcess1" name="Event sub Process" triggeredByEvent="true">
<startEvent id="errorstartevent1" name="Error start">
<errorEventDefintion errorRef="connectError">errorEventDefinition>
startEvent>
<serviceTask id="userTask1" name="Sub Task" activiti:class="ErrorDelegate">serviceTask>
<endEvent id="endevent1" name="End">endEvent>
<sequenceFlow id="flow2" name="" sourceRef="errorstartevent1" targetRef="usertask1">sequenceFlow>
<sequenceFlow id="flow3" name="" sourceRef="usertask1" targetRef="endevent1">sequenceFLow>
subprocess>
<serviceTask id="servicetask1" name="Service Task" activiti:class="erverDelegate">serviceTask>
<endEvent id="endevent2" name="End">endEvent>
<sequenceFlow id="flow4" name="" sourceRef="startevent1" targetRef="serviceTask1">sequenceFlow>
<sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="endevent2">sequenceFlow>
process>
try{
System.out.println("开始检查8080端⼝");
//8080
连接本机的端⼝
Socket socket = new Socket("127.0.0.1",8080);
System.out.println("检查8080端⼝完成");
}catch(Exception e){
System.out.println("检查时出现异常, 抛出错误");
//,BpmError,error code"error"
连接出现异常则抛出且为
throw new org.activiti.engine.delegate.BpmnError("error");
}
4 结束事件
4.1 ⽆指定结束事件
与⽆指定开始事件⼀样,⽆指定结束事件是指流程在结束时,不会进⾏任务的额外操作,结束事件中不使⽤任何事件的定义.
<process id="myProcess" name="myProcess">
<startEvent id="startEvent1" name="Start">startEvent>
<userTask id="userTask1" name="User Task">userTask>
<endEvent id="endEvent1" name="End">endEvent>
<sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="usertask1">sequenceFLow>
<sequenceFlow id="flow2" name="" sourceRef="userTask1" targetRef="endevent1">sequenceFlow>
process>
4.2 错误结束事件
当执⾏流到达错误结束事件时,会结束该执⾏流并且抛出错误,该错误可以被"错误边界事件"捕获,如果没有定义任何的错误边界事件,那么其将
//
部署流程⽂件
repositoryService.createDeployment().addClasspathResource("bpmn/").deploy();
//
启动流程
runtimeService.startProcessInstanceByKey("errorEndProcess");
//,
结束⼦流程中的任务并设置结束任务
Task subTask = taskService.createTaskQuery().singleResult();
Map<String,Object> vars = new HashMap<String,Object>();
//successtrue
设置参数为
vars.put("success","true");
taskService.complete(sybTask.getId(),vars);
//
查看到达的任务
List<Task> tasks = taskService.createTaskQuery().list();
for(Task task : tasks){
System.out.println(task.getName());
}
4.3 取消结束事件和取消边界事件
取消结束事件只能在事务⼦流程中使⽤,该事件表⽰事务将会取消,并且会触发依附在事务⼦流程上的取消边界事件,与错误结束事件类似,取消
结束事件会被抛出,⽽取消边界事件则会捕获该事件.事务⼦流程的取消事件的触发,还会导致补偿的触发.
//
部署流程⽂件
repositoryService.createDeployment().addClasspathResource("bpmn/").deploy();
//
启动流程
runtimeService.startProcessInstanceByKey("cancleProcess");
//
初始化流程参数
Map<String,Object> vars = new HashMap<String,Object>();
vars.put("confirm",false);
// ,task
设置参数完成⽤户确认的
Task task = taskService.createTaskQuery().singleResult();
taskService.complete(task.getId(),vars);
4.4 中⽌结束事件
当流程执⾏到终⽌结束事件时,当前的流程将会被终结,该事件可以在嵌⼊⼦流程,调⽤⼦流程,事件⼦流程或者事务⼦流程中使⽤…终⽌结束事
件使⽤terminateEventDefinition元素作为事件定义.如果将元素的activiti:terminateAll属性设置为true,bane当终⽌结束事件被触发时,流
程实例的全部执⾏流均会被终结.
...//
部署流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("terminateAll");
//
查询执⾏流数量
long exeCount = runtimeService.createExecutionQuery().processInstanceId(pi1.getId()).count();
5 边界事件
BPMN2.0中定义了以下边界事件:消息(Message)边界事件,定时器边界事件,升级边界事件,错误边界事件,取消边界事件,补偿边界事件,条件
边界事件,信号边界事件,组合边界事件和并⾏组合边界事件
6 中间事件
中间事件按照其特性可以分为两类:中间catching事件和Throwing事件,当流程到达中间Catching事件时,它会⼀直等待,直到接收信息,还会


发布评论