我们可以看下图,关于事件相关的矩阵图形,展现了各种BPMN中的图案效果。
事件分类方式:
1、按照位置分类:
开始事件 - 表示流程的开始,使用哪种方式触发流程的开始就是对应各个不同的开始事件。
中间事件 - 出现在流程中可以单独作为一个流程节点展示的事件。
结束事件 - 标志流程结束,分为正常结束、异常结束与执行完成后抛出一个消息或信号。
2、按照特性分类:
捕获事件(Catching) - 是一直在等待被触发的事件,比如所有开始事件都是被等待触发的事件。
抛出事件(Throwing) - 是执行到某一节点自动执行并抛出结果,比如结束事件可以自动执行并返回结果。
3、按照事件定义分类:
定时事件 - 可以作为开始事件与捕获事件及边界事件。
错误事件 - 图中为闪电的是错误事件,可以为中断子过程事件、中断便捷事件与结束事件。
信号事件 - 存在所有的维度。
消息事件 - 存在所有的维度。
对BPMN的事件进行分类后开始对具体事件进行介绍。
定时事件
定义:
- 指定时间(timeDate) - 给事件指定执行的时间
- 指定持续时间(timeDuration) - 例如流程部署五分钟或十分钟后执行。
- 周期执行(timeCycle) - 可以与指定持续时间相结合,例如部署后五分钟执行,然后每十分钟执行一次、
下面举个例子:
<timerEventDefinition>
<timeDate>2019-03-03T11:11:00</timeDate>
</timerEventDefinition>
在timeEventDefinition标签中指定定时事件的类型,这里使用指定时间类型,将会在2019年3月3日十一点十一分执行。
然后我们看看一个简单的定时事件流程:
流程图定义文件如下:
<startEvent id="timerstartevent" name="Timer start">
<timerEventDefinition>
<timeCycle>R5/PT5M</timeCycle>
</timerEventDefinition>
</startEvent >
定时边界事件
流程图例子:
这个流程是正常执行流程时,如果超时,则执行Timeout Task事件再结束。
流程定义文件如下:
<userTask id="commonTask" name="Common Task"></userTask>
<boundaryEvent id="boundarytimer" name="Timer"
attachedToRef="commonTask" cancelActivity="true">
<timerEventDefinition>
<timeDuration>PT5H</timeDuration>
</timerEventDefinition>
</boundaryEvent>
接下来我们使用代码来测试一下:
1、首先创建maven项目,并创建测试流程图
创建好maven项目后,在resources中创建 my-process-timer-boundary.bpmn20.xml 流程定义文件:
流程定义文件内容如下:
<?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: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/test">
<process id="my-process">
<startEvent id="startEvent" name="startEvent"/>
<userTask id="commonTask" name="Common Task"/>
<boundaryEvent attachedToRef="commonTask" id="boundaryEvent"
name="Timer" cancelActivity="true"> <!-- 定义边界事件,并且可以取消这个流程 -->
<timerEventDefinition> <!-- 定义时间定义器 -->
<timeDuration>PT5S</timeDuration> <!-- 流程部署后5秒再执行 -->
</timerEventDefinition>
</boundaryEvent>
<userTask id="timeoutTask" name="Timeout Task"></userTask> <!-- 如果commonTask没有在规定时间内完成,则执行这个userTask -->
<endEvent id="end1"></endEvent>
<endEvent id="end2"></endEvent>
<!-- 然后将事件相连,使用sequenceFlow -->
<sequenceFlow sourceRef="startEvent" targetRef="commonTask"/>
<sequenceFlow sourceRef="commonTask" targetRef="end1"/>
<sequenceFlow sourceRef="boundaryEvent" targetRef="timeoutTask"/>
<sequenceFlow sourceRef="timeoutTask" targetRef="end2"/>
</process>
</definitions>
这里定义了两个事件,一个普通事件与一个边界时间,如果超时则执行 timeoutTask 事件。
2、修改 activiti.cfg.xml 流程定义配置
修改后内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000;MVCC=TRUE" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
<property name="asyncExecutorActivate" value="true"/> <!-- 因为涉及到定时任务,所以要把异步执行器打开 -->
<property name="enableDatabaseEventLogging" value="true"/> <!-- 为了看执行原理,要开启一个可见的日志 -->
</bean>
</beans>
除了基本的数据库配置后,添加了两项内容:因为涉及到定时任务,所以要把异步执行器打开;并且为了更方便的看执行原理,还打开了一个可见的日志。
3、创建 TimerEventTask 测试类
首先在test下创建bpmn20包再创建 TimerEventTask 测试类:
测试类的内容如下:
package com.jjf.activiti.bpmn20;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* test
*/
public class TimerEventTask {
private static final Logger LOGGER = LoggerFactory.getLogger(TimerEventTask.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
@Deployment(resources = {"my-process-timer-boundary.bpmn20.xml"})
public void testTimerBoundary() throws InterruptedException {
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process"); //启动这个流程
List<Task> tasks = activitiRule.getTaskService().createTaskQuery().listPage(0, 100); //查询Task列表
for (Task task:tasks){ //遍历输出task
LOGGER.info("task.name = [{}]" , task.getName());
}
LOGGER.info("task.size = [{}]" , tasks.size());
Thread.sleep(1000*15); //让程序睡眠15s
//再重新执行看看遍历的task事件
tasks = activitiRule.getTaskService().createTaskQuery().listPage(0, 100); //查询Task列表
for (Task task:tasks){ //遍历输出task
LOGGER.info("task.name = [{}]" , task.getName());
}
LOGGER.info("task.size = [{}]" , tasks.size());
}
}
这里我们启动流程后输出此时的task,然后使用Thread让程序睡眠15s后再重新执行查看遍历出来的task事件。
4、测试执行
单元测试结果如下:
Loading XML bean definitions from class path resource [activiti.cfg.xml]
Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
ProcessEngine default created
Starting up the default async job executor [org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor].
Creating thread pool queue of size 100
Creating executor service with corePoolSize 2, maxPoolSize 10 and keepAliveTime 5000
{} starting to acquire async jobs due
{} starting to acquire async jobs due
{} starting to reset expired jobs
task.name = [Common Task]
task.size = [1]
task.name = [Timeout Task]
task.size = [1]
可以看到我们这里睡眠了15s后则会执行Timeout Task事件。