Activiti总体框架分析
参考资料
- activiti数据表结构
- Activiti 5.16 用户手册
- Activiti User Guide
- activiti与BPMN
- activiti源码
- activiti_doc文档
Engine解析
package | 描述 |
---|---|
org.activiti.engine |
流程引擎公共API方法,均采用链式方式 一般通过ProcessEngineConfiguration创建 可以获得的服务包括: |
org.activiti.engine.impl |
engine模块的核心,包含了: pvm的实现 接口方法的实现 命令模式 |
org.activiti.engine.cfg | 配置接口 |
org.activiti.engine.ProcessEngine | 引擎接口 |
org.activiti.engine.ProcessEngineConfiguration | 配置管理 |
org.activiti.engine.ActivitiException | 基础异常类 |
org.activiti.engine.delegate | |
org.activiti.engine.form | 表单信息,和FormService相关联 |
org.activiti.engine.history | 流程历史信息,和HistoryService相关联 |
org.activiti.engine.identity | 用户、组管理信息,和IdentityService相关联 |
org.activiti.engine.logging | 日志 |
org.activiti.engine.management | 流程管理和控制信息,和ManagementService相关联 |
org.activiti.engine.repository | 流程资源信息,和RepositoryService相关联 |
org.activiti.engine.runtime | 流程运行时相关信息,和RuntimeService相关联 |
org.activiti.engine.task | 表示任务相关信息,和TaskService相关联 |
1. org.activiti.engine
定义了流程管理服务的接口:
RepositoryService
、RuntimeService
、FormService
、TaskService
、HistoryService
、IdentityService
、ManagementService
。定义了引擎配置管理接口
ProcessEngineConfiguration
。定义了activiti异常类
ActivitiException
。
org.activiti.engine是activiti的核心功能,控制工作流的流转。几个核心的类如下图所示:
1.1 ProcessEngine
ProcessEngine
接口继承EngineServices
,EngineServices
包括很多工作流/BPM方法的服务,它们都是线程安全的。EngineServices
提供的服务包括:
RepositoryService:
提供了管理和控制流程定义的操作。RuntimeService:
提供了管理和控制流程实例的操作。FormService:
提供了管理流程表单的操作,即使不用FormService
,activiti也可以完美运行。TaskService:
提供了任务管理的操作,包括实例任务挂起
、激活
、完成
、暂停
、查询
。HistoryService:
提供对历史流程,历史任务,历史变量的查询操作。IdentityService:
提供用户和组管理的操作(创建,更新,删除,查询...)。ManagementService:
提供了查询和管理异步操作(定时器,异步操作, 延迟暂停、激活等)的功能,它还可以查询到数据库的表和表的元数据。
EngineServices
代码如下所示:
public interface EngineServices {RepositoryService getRepositoryService();RuntimeService getRuntimeService();FormService getFormService();TaskService getTaskService();HistoryService getHistoryService();IdentityService getIdentityService();ManagementService getManagementService();ProcessEngineConfiguration getProcessEngineConfiguration();}
ProcessEngine
代码如下所示:
public interface ProcessEngine extends EngineServices {/** the version of the activiti library */public static String VERSION = "5.17.0.2";/** The name as specified in 'process-engine-name' in* the activiti.cfg.xml configuration file.* The default name for a process engine is 'default */String getName();void close();}
1.2 ProcessEngineConfiguration
ProcessEngineConfiguration
是配置管理类,它管理的对象包括ProcessEngine,XXservice,数据库session等。ProcessEngineConfiguration
的配置,activiti默认会从activiti.cfg.xml中读取,也可以在Spring的配置文件中读取。ProcessEngineConfiguration
的实现包括:
ProcessEngineConfigurationImpl
继承ProcessEngineConfiguration
,实现了各种Service的初始化StandaloneProcessEngineConfiguration
是单独运行的流程引擎,继承ProcessEngineConfigurationImpl
。代码如下:public class StandaloneProcessEngineConfiguration extends ProcessEngineConfigurationImpl {@Overrideprotected CommandInterceptor createTransactionInterceptor() {return null;} }
StandaloneInMemProcessEngineConfiguration
是单元测试时的辅助类,继承StandaloneProcessEngineConfiguration
,默认使用H2内存数据库。数据库表会在引擎启动时创建,关闭时删除。代码如下所示:public class StandaloneInMemProcessEngineConfiguration extends StandaloneProcessEngineConfiguration {public StandaloneInMemProcessEngineConfiguration() {this.databaseSchemaUpdate = DB_SCHEMA_UPDATE_CREATE_DROP;this.jdbcUrl = "jdbc:h2:mem:activiti";} }
SpringProcessEngineConfiguration
是Spring环境下使用的流程引擎。JtaProcessEngineConfiguration
单独运行的流程引擎,并使用JTA事务。
1.3 ActivitiException
activiti的基础异常类是org.activiti.engine.ActivitiException
,一个非检查异常。Activiti的异常都是通过org.activiti.engine.ActivitiException
抛出,但存在以下特殊情况:
ActivitiWrongDbException:
当Activiti引擎发现数据库版本号和引擎版本号不一致时抛出。ActivitiOptimisticLockingException:
对同一数据进行并发方法并出现乐观锁时抛出。ActivitiClassLoadingException:
当无法找到需要加载的类或在加载类时出现了错误(比如,JavaDelegate,TaskListener等。ActivitiObjectNotFoundException:
当请求或操作的对应不存在时抛出。ActivitiIllegalArgumentException:
这个异常表示调用Activiti API时传入了一个非法的参数,可能是引擎配置中的非法值,或提供了一个非法制,或流程定义中使用的非法值。ActivitiTaskAlreadyClaimedException:
当任务已经被认领了,再调用taskService.claim(...)就会抛出。BpmnError:
流程部署错误,如流程定义文件不合法。JobNotFoundException:
JOB不存在。
2. org.activiti.engine.impl
实现了流程管理服务
RepositoryServiceImpl
,RuntimeServiceImpl
,FormServiceImpl
,TaskServiceImpl
,HistoryServiceImpl
,IdentityServiceImpl
,ManagementServiceImpl
实现流程虚拟机PVM
数据持久化,脚本任务,条件表达式EL的解析等等
命令接口的定义
package | 描述 |
---|---|
org.activiti.engine.impl.asyncexecutor | job调度,主要管理调度线程 |
org.activiti.engine.impl.bpmn | 部署文件,BPMN元素管理 |
org.activiti.engine.impl.calendar | 时间,日期管理 |
org.activiti.engine.impl.cfg | ProcessEngineConfiguration的实现 |
org.activiti.engine.impl.cmd | 命令模式的client,实现了各种命令 |
org.activiti.engine.impl.context | 上下文定义文件,保存线程数据 |
org.activiti.engine.impl.db | 数据库基本增删改操作 |
org.activiti.engine.impl.delegate | 任务监听 |
org.activiti.engine.impl.el | 表达式解析,执行 |
org.activiti.engine.impl.event | 事件 |
org.activiti.engine.impl.form | 表单 |
org.activiti.engine.impl.history | 历史 |
org.activiti.engine.impl.interceptor | 拦截器的定义 |
org.activiti.engine.impl.javax.el | ???? |
org.activiti.engine.impl.jobexecutor | 控制job的执行 |
org.activiti.engine.impl.juel | 对el的扩展 |
org.activiti.engine.impl.persistence | 数据库实体的定义 |
org.activiti.engine.impl.pvm | 流程虚拟机,整个流程的流转,分支该怎么走都靠它了 |
org.activiti.engine.impl.transformer | 基础类型转换,Long转String之类的 |
org.activiti.engine.impl.ServiceImpl | 流程管理服务类 |
2.1 org.activiti.engine.impl.ServiceImpl
XXService
的定义org.activiti.engine.impl.ServiceImpl
是流程管理服务的基类,它的派生类包括RepositoryServiceImpl
,RuntimeServiceImpl
,FormServiceImpl
,TaskServiceImpl
,HistoryServiceImpl
,IdentityServiceImpl
,ManagementServiceImpl
,它定义了配置管理服务processEngineConfiguration
、命令执行接口commandExecutor
(activiti方法调用都通过命令模式)。源码如下所示:public class ServiceImpl {protected ProcessEngineConfigurationImpl processEngineConfiguration;public ServiceImpl() {}public ServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {this.processEngineConfiguration = processEngineConfiguration;}protected CommandExecutor commandExecutor;public CommandExecutor getCommandExecutor() {return commandExecutor;}public void setCommandExecutor(CommandExecutor commandExecutor) {this.commandExecutor = commandExecutor;}}
XXServiceImpl
继承类org.activiti.engine.impl.ServiceImpl
,并且实现对应的XXService
接口。下面是RepositoryServiceImpl
示例代码:public class RepositoryServiceImpl extends ServiceImpl implements RepositoryService {}
XXService
的初始化XXService
的初始化在ProcessEngineConfigurationImpl中protected RepositoryService repositoryService = new RepositoryServiceImpl(); protected RuntimeService runtimeService = new RuntimeServiceImpl();protected HistoryService historyService = new HistoryServiceImpl(this);protected IdentityService identityService = new IdentityServiceImpl();protected TaskService taskService = new TaskServiceImpl(this);protected FormService formService = new FormServiceImpl();protected ManagementService managementService = new ManagementServiceImpl();
XXService
的commandExecutor
初始化在ProcessEngineConfigurationImpl的initService中protected void initService(Object service) {if (service instanceof ServiceImpl) {((ServiceImpl)service).setCommandExecutor(commandExecutor);} }
2.2 org.activiti.engine.impl.interceptor
包org.activiti.engine.impl.interceptor
定义了拦截器和命令。activiti里面所有的指令都是通过命令模式执行,在命令执行之前,可以切入多个拦截器。
commandContext
是命令上下文。command
是命令接口,command
中定义了execute
方法,代码如下所示:public interface Command <T> {T execute(CommandContext commandContext); }
CommandExecutor
这个是命令的执行方法,CommandConfig
是CommandExecutor
的配置。CommandExecutor
代码如下所示:public interface CommandExecutor {/*** @return the default {@link CommandConfig}, used if none is provided.*/CommandConfig getDefaultConfig();/*** Execute a command with the specified {@link CommandConfig}.*/<T> T execute(CommandConfig config, Command<T> command);/*** Execute a command with the default {@link CommandConfig}.*/<T> T execute(Command<T> command);}
CommandInterceptor
拦截器,在命令执行之前进行拦截,一个命令可以有多个拦截器,这些拦截器通过链表链接起来顺序执行。CommandInterceptor
代码如下:public interface CommandInterceptor {<T> T execute(CommandConfig config, Command<T> command);CommandInterceptor getNext();void setNext(CommandInterceptor next);}
commandExecutor到底是如何注入的?
以
RuntimeServiceImpl
为例,RuntimeServiceImpl
继承类ServiceImpl
,ServiceImpl
包含CommandExecutor
属性在
ProcessEngineConfigurationImpl
中有个init方法,里面有对于executor和intecerptor的初始化// 初始化各种服务 protected void initServices() {initService(repositoryService);initService(runtimeService);initService(historyService);initService(identityService);initService(taskService);initService(formService);initService(managementService); }// 初始化服务方法 protected void initService(Object service) {if (service instanceof ServiceImpl) {((ServiceImpl)service).setCommandExecutor(commandExecutor);} }// 初始化拦截器 protected void initCommandInterceptors() {if (commandInterceptors==null) {commandInterceptors = new ArrayList<CommandInterceptor>();if (customPreCommandInterceptors!=null) {commandInterceptors.addAll(customPreCommandInterceptors);}commandInterceptors.addAll(getDefaultCommandInterceptors());if (customPostCommandInterceptors!=null) {commandInterceptors.addAll(customPostCommandInterceptors);}commandInterceptors.add(commandInvoker);} }// 将拦截器初始化成链式结构 protected void initCommandExecutor() {if (commandExecutor==null) {CommandInterceptor first = initInterceptorChain(commandInterceptors);commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);} }
2.3 org.activiti.engine.impl.delegate
包org.activiti.engine.impl.delegate
实现了监听器和事件处理,activiti 允许客户端代码介入流程的执行,为此提供了这个基础组件。
activiti5.16 用户手册的介绍,监听器,事件处理。
2.3.1 监听器
监听器可以捕获的事件包括:
- 流程实例的启动和结束
- 选中一条连线
- 节点的开始和结束
- 网关的开始和结束
- 中间事件的开始和结束
- 开始时间结束或结束事件开始
DelegateInterceptor
是事件拦截器接口,DelegateInvocation
是事件调用接口,XXXInvocation
是DelegateInvocation
的实现类,XXXInvocation
里面包含监听接口XXXListener
。
怎样添加监听
下面的流程定义文件包含2个监听器,
event
表示时间类型,class
表示处理事件的java类。<extensionElements><activiti:taskListener event="create" class="com.alfrescoblog.MyTest.imple.CreateTaskDelegate"></activiti:taskListener><activiti:taskListener event="complete" class="com.alfrescoblog.MyTest.imple.MyJavaDelegate"></activiti:taskListener> </extensionElements>
``CreateTaskDelegate
是客户端实现的监听类,TaskListener
是activiti的监听接口。
package com.alfrescoblog.MyTest.imple;import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;public class CreateTaskDelegate implements TaskListener {public void notify(DelegateTask delegateTask) {// TODO Auto-generated method stubSystem.out.println("创建任务啦!!"); }}
TaskListener
代码如下所示:
public interface TaskListener extends Serializable {String EVENTNAME_CREATE = "create";String EVENTNAME_ASSIGNMENT = "assignment";String EVENTNAME_COMPLETE = "complete";String EVENTNAME_DELETE = "delete";/*** Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,* including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.*/String EVENTNAME_ALL_EVENTS = "all";void notify(DelegateTask delegateTask);}
监听怎样被注入的
BPMN流程文件部署的时候会注入各种listener。比如TaskListener在org.activiti.engine.impl.task.TaskDefinition的addTaskListener方法中被注入,代码如下:
public void addTaskListener(String eventName, TaskListener taskListener) {if(TaskListener.EVENTNAME_ALL_EVENTS.equals(eventName)) {// In order to prevent having to merge the "all" tasklisteners with the ones for a specific eventName,// every time "getTaskListener()" is called, we add the listener explicitally to the individual liststhis.addTaskListener(TaskListener.EVENTNAME_CREATE, taskListener);this.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, taskListener);this.addTaskListener(TaskListener.EVENTNAME_COMPLETE, taskListener);this.addTaskListener(TaskListener.EVENTNAME_DELETE, taskListener);} else {List<TaskListener> taskEventListeners = taskListeners.get(eventName);if (taskEventListeners == null) {taskEventListeners = new ArrayList<TaskListener>();taskListeners.put(eventName, taskEventListeners);}taskEventListeners.add(taskListener);} }
监听在什么时候触发的
以TaskListener为例,调用链:
UserTaskActivityBehavior.execute()
→task.fireEvent(TaskListener.EVENTNAME_CREATE);
→DelegateInterceptor.handleInvocation()
→DefaultDelegateInterceptor.handleInvocation()
→DelegateInvocation.proceed()
→TaskListenerInvocation.invoke()
→TaskListener.notify()
UserTaskActivityBehavior
是任务新增、修改、删除行为,UserTask节点解析(UserTaskParseHandler.executeParse)的时候设置到activiti中,触发的代码还没找到。protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, userTask, BpmnXMLConstants.ELEMENT_TASK_USER);activity.setAsync(userTask.isAsynchronous());activity.setExclusive(!userTask.isNotExclusive());TaskDefinition taskDefinition = parseTaskDefinition(bpmnParse, userTask, userTask.getId(), (ProcessDefinitionEntity) bpmnParse.getCurrentScope().getProcessDefinition());activity.setProperty(PROPERTY_TASK_DEFINITION, taskDefinition);activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask, taskDefinition)); }
from:
https://haibinpark.gitbooks.io/activiti-develop-plan/content/activiti_analysis/whole_framework.html#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99
Activiti总体框架分析相关推荐
- Activiti源码分析(框架、核心类。。。)
Activiti源码分析(框架.核心类...) 目录 概 述 activiti源码分析(一)设计模式 总结: 相关工具如下: 分析: 小结: 参考资料和推荐阅读 LD is tigger foreve ...
- Linux PCI驱动框架分析:(Peripheral Component Interconnect,外部设备互联)
<DPDK 20.05 | rte_pci_bus思维导图 | 第一版> <linux系统下:IO端口,内存,PCI总线 的 读写(I/O)操作> <Linux指令:ls ...
- 【backtrader源码解析52】indicators部分代码解读(枯燥,仅供参考,源代码解析结束,后面会增加一个backtrader框架分析)
指标类里面有很多不同的指标,如果对如何使用指标做策略感兴趣的话,可以考虑阅读下相关的源码和指标的用法,就仅仅指标的源代码而言,似乎没有什么可讲的.另外,关于backtrader源代码的注释,放到网站上 ...
- Linux PCIe驱动框架分析(第二章)
目录 项目背景 1. 概述 2. 数据结构 3. 流程分析 3.1 设备驱动模型 3.2 初始化 3.2.1 pci_bus_match 3.2.2 pci_device_probe 3.3 枚举 项 ...
- skydive前端代码框架分析
skydive前端代码: https://github.com/skydive-project/skydive/tree/master/statics 前端代码使用框架分析: 以vue-2.1.9框架 ...
- 《机械制造业智能工厂规划设计》——3.3 机械制造业智能工厂总体框架
3.3 机械制造业智能工厂总体框架 机械制造业智能工厂的总体框架如图3.8所示.在信息物理融合系统的CPS的支持下,构建智能设计.智能产品.智能经营.智能服务.智能生产.智能决策六大系统.通过企业信息 ...
- 《机械制造业智能工厂规划设计》——第3章 机械制造业智能工厂的总体框架 3.1 智能制造的通用定义和特征...
第3章 机械制造业智能工厂的总体框架 3.1 智能制造的通用定义和特征 1.智能制造的定义和内涵 智能制造系统(Intelligent Manufacturing System,IMS)是一种由智能机 ...
- 智慧产业园区标准体系总体框架
导读: 智慧产业园区类似一个"城市",是一个包括产业发展.技术开发和学术研究在内的综合体.各组成部分协调运转.良性循环.相互促进,最终激发企业创新活力和产业市场潜力.智慧产业园区不 ...
- Linux输入事件类型EV_SW,Linux的input输入子系统:总体框架
一.input输入子系统总体框架 Linux输入子系统将输入驱动抽象为三层:设备驱动层.核心层.事件处理层. 设备驱动层:将底层的硬件输入事件转化为统一事件形式,向输入核心(Input Core)汇报 ...
最新文章
- php smarty csv,6个smarty小技巧
- CubieBoard开发板数据源介绍
- CodeForces - 126B Password(KMP中next数组)
- 运营商市场经营方向及趋势
- 从系统集成到虚拟化,IT之路艰难前行...
- python 循环控制语句结束,Python是如何循环控制语句的
- 关于SQLServer2005的学习笔记——异常捕获及处理
- 3、grep,vim,压缩功能详解
- 强化学习入门笔记(一)——莫烦Python
- “运行时错误‘339‘部件‘flash8.ocx‘或其附件之一不能正确注册:一个文件丢失或无效“的一种解决办法!
- c软件查表获得电量代码_energy.c 源代码在线查看 - 基于单片机的多费率电能表源程序 资源下载 虫虫电子下载站...
- uni-app 从本地项目选择图片或使用相机拍照及图片预览
- Java并没有失去它的魔力
- 2020多益网络游戏开发工程师笔试
- 图片上传实时预览效果
- java使用poi操作ppt(导入,导出,读取,添加,拼接,替换文本,页面排序)
- 【车载以太网】【SOME/IP】规范标准
- 显示器接口:VGA、HDMI、DVI 、DisplayPort
- A3Mall开源商城系统
- ASII码中控制字符CR和LF的含义
热门文章
- group by 和 having(转载)
- android parcelable 详细介绍
- NLP—word2vec词向量简介
- AlphaGo已经拿下围棋,创投界的“Master”何时出现?
- 几周内搞定Java的10个方法
- SpringBoot - 优雅的实现【参数分组校验】高级进阶
- Apache ZooKeeper - 构建ZooKeeper源码环境及StandAlone模式下的服务端和客户端启动
- python 替换空格
- 5m 云服务器2核4g_阿里云服务器2核4gb
- python命令式编程的概念,【Python】十分钟学会函数式编程