Activiti工作流学习-----基于5.19.0版本(2)
二、activiti.cfg.xml的其他bean节点配置
2.1 新特性:Job Executor和Async Executor
从5.17.0版本的activiti开始提供作业执行者(Job Executor)和异步作业执行者(Async Executor),Async Executor执行表现更好,并且执行异步作业对数据库更加友善。activiti官方推荐使用Async Executor,并且一些老的Job Executor依旧有效。在Java EE 7运行环境中,JSR-236规范支持容器管理ManagedJobExecutor和ManagedAsyncJobExecutor,例如可以配置如下:
<bean id="threadFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/ee/concurrency/factory/default" />
</bean> <bean id="customJobExecutor" class="org.activiti.engine.impl.jobexecutor.ManagedJobExecutor">
<!-- ... -->
<property name="threadFactory" ref="threadFactory" />
<!-- ... -->
</bean>
2.2 激活Job executor
Job executor作为管理多线程执行定时任务的组件,在单元测试场景里,Job executor在多线程中执行是测试不方便的,所以activiti提供了api解决了这个麻烦:
查询获取Job executor可以通过ManagementService.createJobQuery方法实现,执行该作业可以调用ManagementService.executeJob,使得在单元测试中Job executor可以被控制,顺利关闭Job executor。默认的Job executor是在流程引擎启动就被激活的,如果需要关闭这个功能,可以配置:
<property name="jobExecutorActivate" value="false" />
2.3 激活Async executor
AsyncExecutor作为管理线程池执行定时任务的组件,默认activiti是关闭AsyncExecutor的,使用它的配置如下:
<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="true" />
asyncExecutorEnabled属性设置设置true后将代替那些老的Job executor,第二个属性asyncExecutorActivate是指示activiti在流程引擎启动就激活AsyncExecutor。
2.4 流程定义缓存配置
所有被解析的流程定义都会被缓存起来,这是因为流程定义是不会改变的,没有必要多次请求数据库。默认的activiti是没有限制缓存数量的,如果需要设置:
<property name="processDefinitionCacheLimit" value="10" />
缓存内部是使用HashMap数据结构和LRU算法实现的。当然,缓存的数量的设置值最好根据流程定义的总数和正在运行的流程实例使用的流程定义数量决定。你也可以使用自定义的缓存实现类替换内部提供的缓存实现,只需要实现接口org.activiti.engine.impl.persistence.deploy.DeploymentCache,然后配置即可:
<property name="processDefinitionCache">
<bean class="org.activiti.MyCache" />
</property>
对于自定义缓存实现的缓存数量限制可以设置knowledgeBaseCacheLimit和knowledgeBaseCache属性。
2.5 日志
在activiti 5.12的时候,日志框架使用的是SLF4J,替换掉早前的jdk的日志工具,现在所有的日志(activiti, spring, mybatis, …)都通过SLF4J来输出日志,你可以具体的日志实现。
工作流没有提供日志的具体实现jar包在依赖里面,需要你自己手动添加,如果没有添加,SLF4J会全程使用NOP-logger,它不会全程记录所有的日志的,并且警告没有被记录,在Maven中比如添加log4j:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
activiti-explorer和activiti-rest项目是使用的log4j,activiti项目测试也是使用的log4j记录日志。
如果你的类路径下面已经有了commons-logging的jar了的话,这时需要commons-logging干的活交给slf4j,比如要让spring输出日志使用slf4j的话,需要使用依赖:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
如果使用的服务器是Tomcat,需要注意tomcat自己的类路径下面也有日志的jar包,解决办法参考:http://www.slf4j.org/codes.html#release
2.6 日志配置相关工作流上下文
从版本5.13开始,Activiti支持使用slf4j记录工作流上下文,日志通过底层日志logger记录的内容有:
processDefinition Id ------ mdcProcessDefinitionID
processInstance Id ------- mdcProcessInstanceID
execution Id - ---- mdcexecutionId
日志记录有格式化的信息和其他的普通信息,例如日志记录可以配置:
log4j.appender.consoleAppender.layout.ConversionPattern =ProcessDefinitionId=%X{mdcProcessDefinitionID}
executionId=%X{mdcExecutionId} mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %m%n"
2.7 事件处理
在Activiti 5.15中引入了事件机制,它让你在工作流引擎中的各种事件发生时得到消息,activiti能够支持注册一个侦听器对于某些类型的事件而不是任何类型的事件发生时收到通知,一方面可以在配置文件中添加engine-wide事件监听器配置,然后engine-wide事件监听器类会调用相应的API,另一方面也可以在在BPMN配置文件中配置。
所有的事件类都是org.activiti.engine.delegate.event.ActivitiEvent的子类,事件会提供type、executionId、processInstanceId和processDefinitionId,某些事件包含了事件发生的上下文,附加载荷的信息。
2.8 事件监听器的实现
事件监听器需要实现org.activiti.engine.delegate.event.ActivitiEventListener,例如:
public class MyEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
switch (event.getType()) {
case JOB_EXECUTION_SUCCESS:
System.out.println("A job well done!");
break;
case JOB_EXECUTION_FAILURE:
System.out.println("A job has failed...");
break;
default:
System.out.println("Event received: " + event.getType());
}
}
@Override
public boolean isFailOnException() {
// The logic in the onEvent method of this listener is not critical, exceptions
// can be ignored if logging fails...
return false;
}
}
MyEventListener接收标准事件类型并处理和异常处理,其中isFailOnException()决定了onEvent(..)是否抛出异常,如果返回false,异常将会被忽略。如果返回true,异常将会逐级向上提交,
造成当前运行的命令的失败。如果当前执行具有事务,事务将会回滚。activiti官方建议如果事件的业务不是非常重要,还是返回false。
activiti提供了通用的实现类来处理普通的事件监听,例如:
org.activiti.engine.delegate.event.BaseEntityEventListener:它将会监听entity类的事件,它隐藏了类型检查和重写了四个方法,onCreate(..), onUpdate(..)和onDelete(..),
对于其他的事件,onEntityEvent(..)将会被调用。 2.9 事件的相关配置 如果一个事件监听器在流程引擎配置,流程引擎启动将会激活,即使重启引擎也会保持该状态。eventListeners属性值为org.activiti.engine.delegate.event.ActivitiEventListener
的实例的list,例如:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
...
<property name="eventListeners">
<list>
<bean class="org.activiti.engine.example.MyEventListener" />
</list>
</property>
</bean>
另外typedEventListeners属性值为Map,key为事件的名称,value表示为一个org.activiti.engine.delegate.event.ActivitiEventListener的list集合,例如:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
...
<property name="typedEventListeners">
<map>
<entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
<list>
<bean class="org.activiti.engine.example.MyJobEventListener" />
</list>
</entry>
</map>
</property>
</bean>
事件发生的顺序取决于被配置的监听器的顺序。首先,所有的普通的监听器会被调用(也就是说eventListeners属性,至于eventListeners的内部的监听器顺序和配置的顺序有关)
,然后是在typedListeners属性配置的会被调用。
2.10 程序运行时动态添加监听器
调用RuntimeService的api方法可以实现这个功能:(注意:系统重启会导致监听器消失)
void addEventListener(ActivitiEventListener listenerToAdd); void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types); void removeEventListener(ActivitiEventListener listenerToRemove);
2.11 添加监听器到流程定义中
在流程定义中添加监听器是允许的,这里定义的监听器会被流程定义相关的事件和所有的相关的流程实例启动后调用,监听器的实现类可以使用全类名、能够被解析为bean的表达式。例如下面这个配置,第一个监听器将接收所有的事件,它使用的是全类名进行配置的,第二个监听器仅仅是在作业执行成功或者失败会被执行,并且使用了在流程引擎中定义的beans属性配置的监听器的表达式。
<process id="testEventListeners">
<extensionElements>
<activiti:eventListener class="org.activiti.engine.test.MyEventListener" />
<activiti:eventListener delegateExpression="${testEventListener}" events="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" />
</extensionElements>
...
</process>
如果我们需要在流程定义中配置监听entity的监听器的话,可以这样配置:
<process id="testEventListeners">
<extensionElements>
<activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" />
<activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" />
</extensionElements>
...
</process>
其中entityType的值有:attachment, comment, execution, identity-link, job, process-instance, process-definition, task。
Activiti工作流学习-----基于5.19.0版本(2)的更多相关文章
- Activiti工作流学习-----基于5.19.0版本(8)
8.1.5 Start Event 继续上一篇的事件的分享笔记,Start Event指明该处是流程开始,至于开始事件的类型(消息到达开始,指定的事件循环开始等),定义如何开始是在开始事件圆圈图标里面 ...
- Activiti工作流学习-----基于5.19.0版本(5)
五.与Spring集成 实际项目中一般都有Spring的身影,与Spring集成使得Activiti的实用性得到提高.activiti和Spring整合需要activiti-spring的jar在类路 ...
- Activiti工作流学习-----基于5.19.0版本(6)
七. BPMN的简介 读者了解到这里,应付一般的工作流开发已经足够了.此处应该有华丽的分割线,在工作流项目中核心开发人员主要是对工作流业务设计以及实现,而初级开发人员是对业务功能的代码实现.以后将主要 ...
- Activiti工作流学习-----基于5.19.0版本(1)
该版本的Activiti运行须知: 1.JDK 6+,Eclipse最好是Kepler以上版本. 2.试验功能都有EXPERIMENTAL标注,被标注的部分不应该视为稳定的. 有兴趣的同学可以去了解下 ...
- Activiti工作流学习-----基于5.19.0版本(4)
四.使用工作流开发 org.activiti.engine.ProcessEngine提供的Service作用在工作流引擎上面,如果所示是模仿一个公司简单的审批流程,你可以下载这个Demo:Activ ...
- Activiti工作流学习-----基于5.19.0版本(7)
八.BPMN 2.0流程图详解 BPMN 2.0的标准的出现是好事,用户不在被某个工作流开发商绑架或者在工作流中开发妥协,Activiti作为BPMN标准的一套解决方案,使得用户在选择工作流框架时可以 ...
- Activiti工作流学习-----基于5.19.0版本(3)
前面关于eventType的属性值的配置简单的说了一下,activiti支持的值如下表所示:这是我摘抄的activiti官网的 Event 的名字 描述 Event的类名 ENGINE_CREATED ...
- Activiti工作流学习之流程图应用详解
Activiti工作流学习之流程图应用详解 1.目的 了解Activiti工作流是怎样应用流程图的. 2.环境准备2.1.相关软件及版本 jdk版本:Jdk1.7及以上 IDE:eclipse ...
- Activiti工作流学习之概述(一)
一.工作流介绍 我第一次听到这个词,是蒙逼的,再看百度百度,更傻眼了,完全说的不像人话啊,举几个生活中的例子,就明白多了比如:请假.报销等等,如果文字太过抽象,请看图: 二.工作流引擎 Process ...
随机推荐
- windows 2003 远程桌面 连接输入账号密码后,只能看见蓝色屏幕和鼠标
具体解决方案参考的 http://www.tomshardware.com/forum/171045-46-remote-desktop-connection-blank-desktop to s ...
- New ipad安装Perl支持安装nikto
Title:New ipad安装Perl支持安装nikto --2012-11-15 09:47 New Ipad 越了后. ssh new ipad 进入目录 cd /tmp 下载Key文件 wge ...
- Android中的手势
Android对两种手势行为提供了支持:1.对于第一种手势行为而言,Android提供了手势检测,并为手势检测提供了相应的监听器.2.对于第二种手势行为,Android允许开发者添加手势,并提供了相应 ...
- Android 实现ActionBar定制
我们在使用Android手机时,经常发现应用中的ActionBar和我们平时使用的ActionBar相差非常大.简单的说就是,其他应用的 ActionBar为什么那么绚丽,自己应用的ActionBar ...
- layer iframe层的使用,传参
父层 <div class="col-xs-4 text-left" style="padding-left: 50px;"><button ...
- HDU_2019——向排序好的数列中插入数
Problem Description 有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序. Input 输入数据包含多 ...
- Node开发入门
介绍 Node.js采用google的V8虚拟机来解释和执行javascript,也就是允许脱离浏览器环境运行javascript代码. Hello World 婴儿说的第一个字一般是"妈& ...
- 关于apriori算法的一个简单的例子
apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...
- Java程序员在用的大数据工具,MongoDB稳居第一!
据日前的一则大数据工具使用情况调查,我们知道了Java程序猿最喜欢用的大数据工具. 问题:他们最近一年最喜欢用什么工具或者是框架? 受访者可以选择列表中的选项或者列出自己的,本文主要关心的是大数据工具 ...
- prepareStatement的用法和解释
1. PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程2. 使用 Statement 对象.在对数据库只执行一次性存取的时侯,用 Statement ...