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 ...
随机推荐
- LINQ TO SQL 常用语法
LINQ To SQL中IN的用法 IN: C# var result = from s1 in context.Customers where (new string[] { "UK& ...
- [LeetCode] 203. Remove Linked List Elements 解题思路
Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...
- Linux下创建、查看、提取和修改静态库(*.a)
先说明一点,静态库文件是由多个目标文件打包而成的,在windows下静态库文件的后缀是.lib,而在linux下静态库文件的后缀是.a(a是archive的缩写,也就是文档文件). 废话少说,下面直接 ...
- Shell脚本常用命令简介
格式化日期yyyy-mm-dd hh:mm:ss显示 date "+%Y-%m-%d %H:%M:%S" 将内容写入到新文件 echo "hello">a ...
- Java[4] Jetty工作原理介绍(转)
转自:https://www.ibm.com/developerworks/cn/java/j-lo-jetty/ Jetty 的工作原理以及与 Tomcat 的比较 Jetty 应该是目前最活跃也是 ...
- http缓存策略
http://foofish.net/blog/95/http-cache-policy
- ASP.net中DateTime获取当前系统时间的大全
在c# / ASP.net中我们可以通过使用DataTime这个类来获取当前的时间.通过调用类中的各种方法我们可以获取不同的时间:如:日期(2008-09-04).时间(12:12:12).日期+时间 ...
- dojo 学习笔记之dojo.query - query(id) 与query(class)的差别
考虑这个样例:动态创建一个页面的时候,用new listtem()生成多个listitem, 且每一个listitem中都生成一个按钮button. 假设想要给每一个按钮都绑定一个click事件,用d ...
- emacs快捷键学习(一)--Linux最强大的编辑器
emacs是一个非常强大的编辑器.经常使用的快捷键总结例如以下: 退出emacs:ctrl+x ctrl+c 移动到下一屏:ctrl+v 移动到上一屏:alt+v 将光标所在行移动到屏幕中间:ctrl ...
- Android中的创建型模式总结
共5种,单例模式.工厂方法模式.抽象工厂模式.建造者模式.原型模式 单例模式 定义:确保某一个类的实例只有一个,而且向其他类提供这个实例. 单例模式的使用场景:某个类的创建需要消耗大量资源,new一个 ...