activiti学习笔记(六) 监听器
时间:2022-05-03
本文章向大家介绍activiti学习笔记(六) 监听器,主要内容包括activiti全局监听器、初始化所有监听器、初始化监听器配置过程、监听器在流程实例启动时候的应用、测试、测试结果、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
activiti全局监听器
全局监听器主要使用的场景就是监控这个流程的启动和结束。流程开始的时候可以监控,流程结束的时候也可以监控
监听器的接口
public interface ActivitiEventListener {
/**当时间被执行时调用该方法*/
void onEvent(ActivitiEvent event);
/**
* @author 郑小康
* 这个是onEvent执行失败之后进行的处理
*
* 如果是true则返回onEvent执行失败的异常
*
* 如果是false则忽略这个异常
* */
boolean isFailOnException();
}
初始化所有监听器
将所有全局监听器和类型监听器给加入到当前eventListeners里面,这里只是初始化过程
/**
* @author 郑小康
*
* 事件监听器分为两种
*
* 1.如果eventDispatcher为空,则实例化ActivitiEventDispatcherImpl
*
* 2.设置eventDispatcher的状态为enableEventDispatcher,其值为true 默认支持事件转发
*
* 3.遍历当前流程实例所有的eventListeners监听器,将其添加到eventDispatcher
*
* 4.遍历所有typedEventListeners 以entry为key进行添加
* 在cfg.xml文件定义:
* <property name="typedEventListeners">
* <map>
* <entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
* <list>
* <bean class="org.activiti.engine.example.MyJobEventListener" />
* </list>
* </entry>
* </map>
* </property>
* */
public void initEventDispatcher() {
if (this.eventDispatcher == null) {
this.eventDispatcher = new ActivitiEventDispatcherImpl();
}
this.eventDispatcher.setEnabled(enableEventDispatcher);
if (eventListeners != null) {
for (ActivitiEventListener listenerToAdd : eventListeners) {
this.eventDispatcher.addEventListener(listenerToAdd);
}
}
if (typedEventListeners != null) {
for (Entry<String, List<ActivitiEventListener>> listenersToAdd : typedEventListeners.entrySet()) {
// Extract types from the given string
ActivitiEventType[] types = ActivitiEventType.getTypesFromString(listenersToAdd.getKey());
for (ActivitiEventListener listenerToAdd : listenersToAdd.getValue()) {
this.eventDispatcher.addEventListener(listenerToAdd, types);
}
}
}
}
初始化监听器配置过程
其实在流程实例中注入相对应的属性bean
<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="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=UTF-8
</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password" value="fadp" />
</bean>
<bean id="processEngine1" name="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="databaseSchemaUpdate" value="true" />
<property name="eventListeners">
<list>
<bean class="com.event.MyEventListener" />
</list>
</property>
</bean>
</beans>
监听器在流程实例启动时候的应用
在构建流程实例的时候,会构建一个流程实例,在器最后会构建一个引擎启动时间,调用所有监听器的onEvent 方法
public ProcessEngineImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
.......
//调用时间转发器,构建一个事件实例ActivitiEvent类型为ENGINE_CREATED,然后进行事件转发
processEngineConfiguration.getEventDispatcher().dispatchEvent(ActivitiEventBuilder.createGlobalEvent(ActivitiEventType.ENGINE_CREATED));
}
/**
* 1.enabled判断,默认为true进行事件转发
*
* 2.FIXME:尚未理解
* */
@Override
public void dispatchEvent(ActivitiEvent event) {
if (enabled) {
eventSupport.dispatchEvent(event);
}
if (event.getType() == ActivitiEventType.ENTITY_DELETED && event instanceof ActivitiEntityEvent) {
ActivitiEntityEvent entityEvent = (ActivitiEntityEvent) event;
if (entityEvent.getEntity() instanceof ProcessDefinition) {
// process definition deleted event doesn't need to be dispatched to event listeners
return;
}
}
CommandContext commandContext = Context.getCommandContext();
if (commandContext != null) {
BpmnModel bpmnModel = extractBpmnModelFromEvent(event);
if (bpmnModel != null) {
((ActivitiEventSupport) bpmnModel.getEventSupport()).dispatchEvent(event);
}
}
}
/**
* @author 郑小康
*
* 1.对当前转化的事件做非空校验
*
* 2.转化所有全局事件监听器
*
* 3.获取跟当前事件类型相同的事件监听器,并进行事件转化进行执行
*
* */
public void dispatchEvent(ActivitiEvent event) {
if (event == null) {
throw new ActivitiIllegalArgumentException("Event cannot be null.");
}
if (event.getType() == null) {
throw new ActivitiIllegalArgumentException("Event type cannot be null.");
}
//执行所有全局事件监听器
if (!eventListeners.isEmpty()) {
for (ActivitiEventListener listener : eventListeners) {
dispatchEvent(event, listener);
}
}
//获取跟当前事件类型相同的事件监听器,并进行事件转化进行执行
List<ActivitiEventListener> typed = typedListeners.get(event.getType());
if (typed != null && !typed.isEmpty()) {
for (ActivitiEventListener listener : typed) {
dispatchEvent(event, listener);
}
}
}
测试
@Test
public void getDefaultProcessEngine() {
ProcessEngineConfiguration pec = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("com/event/activiti.cfg.xml");
ProcessEngine pe1 = pec.buildProcessEngine();
}
测试结果
Event received: ENGINE_CREATED
其中还有一种动态加载监听器的过程,通过第一个流程实例获取监听器的集合,进行添加,在第二个流程实例中就可以这样用了,为什么是这样呢,因为spring获取bean是单例模式,监听器引用类型指向的是同一个变量,使用过程如下:
@Before
public void init() {
processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource(
"com/activiti_study/ch24/activiti1.cfg.xml")
.buildProcessEngine();
repositoryService = processEngine.getRepositoryService();
activitiEventDispatcher = ((ProcessEngineConfigurationImpl) processEngine
.getProcessEngineConfiguration()).getEventDispatcher();
}
@Test
public void testAddEventListener() {
ShareniuTaskEventListener2 shareniuTaskEventListener2 = new ShareniuTaskEventListener2();
activitiEventDispatcher.addEventListener(shareniuTaskEventListener2);
ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
System.out.println(pe);
processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource(
"com/activiti_study/ch24/activiti1.cfg.xml")
.buildProcessEngine();
}
- 入门Webpack(上)
- 碎片化 | 第四阶段-56-ManyToOne和OneToMany映射关系-视频
- 基于网络流量的SDN最短路径转发应用
- 碎片化 | 第四阶段-57-hibernate二级缓存-视频
- NoSQL篇 | NoSQL从小白到码神 之 Redis篇
- Neutron和ONOS集成实践
- 基于OpenDaylight和OVSDB搭建VxLAN网络
- 史上最强----机器学习经典总结---入门必读
- SDNLAB群分享(四):利用ODL下发流表创建VxLAN网络
- Neutron集成ONOS源码分析
- “访问限制”&“代理访问”实验
- OpenDaylight Lithium-SR2 Cluster集群搭建
- Linux | CentOS7下会玩JDK不?你确定?
- Linux | 不懂Linux的码神,不是真正的菜鸟
- 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 数组属性和方法
- Python爬虫实现HTTP网络请求多种实现方式
- 在tensorflow以及keras安装目录查询操作(windows下)
- Python调用OpenCV实现图像平滑代码实例
- php微信公众号开发之音乐信息
- Laravel关联模型中过滤结果为空的结果集(has和with区别)
- php微信公众号开发之二级菜单
- django中的ajax组件教程详解
- php微信公众号开发之校园图书馆
- 查看keras的默认backend实现方式
- Python包和模块的分发详细介绍
- PHP cookie,session的使用与用户自动登录功能实现方法分析
- Python内置方法和属性应用:反射和单例(推荐)
- 使用OpenCV对车道进行实时检测的实现示例代码
- php 读取文件夹下所有图片、文件的实例
- php微信公众号开发之欢迎老朋友