以下教程基于:activiti 5.22 版本
表结构
说明
Activiti一共有25张表其中所有的表都是以 ACT_.* 开始的。
-
ACT_RE_ :RE代表repository。具有此前缀的表包含静态*信息,例如流程定义和流程资源(图像,规则等)。
-
ACT_RU_ :RU*代表runtime。这些是包含流程实例,用户任务,变量,作业等的运行时数据的运行时表。Activiti仅在流程实例执行期间存储运行时数据,并在进程实例结束时删除记录。这使得运行时间表保持不间断的快速。
-
ACT_ID_ :ID*代表identity。这些表包含身份信息,如用户,组等。
-
ACT_HI_ :HI*代表history。这些是包含历史数据的表,例如过去的流程实例,变量,任务等。
-
ACT_GE_ :general数据,用于各种用例。
表分类
日志表
- act_evt_log 表示EVENT,目前只有一张表ACT_EVT_LOG,存储事件处理日志,方便管理员跟踪处理。
通用数据表
-
act_ge_bytearray 二进制数据表 png bpmn 存在这个表
-
act_ge_property 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录
历史数据库表
-
act_hi_actinst 历史节点表
-
act_hi_attachment 历史附件表
-
act_hi_comment 历史意见表
-
act_hi_detail 历史详情表,提供历史变量的查询
-
act_hi_identitylink 历史流程人员表
-
act_hi_procinst 历史流程实例表
-
act_hi_taskinst 历史任务实例表
-
act_hi_varinst 历史变量表
组织机构表
-
act_id_group 用户组信息表
-
act_id_info 用户扩展信息表
-
act_id_membership 用户与用户组对应信息表
-
act_id_user 用户信息表
资源库流程规则表
-
act_procdef_info 流程定义信息
-
act_re_deployment 部署信息表
-
act_re_model 流程设计模型部署表
-
act_re_procdef 流程定义数据表
运行时数据库表
-
act_ru_event_subscr 监听表
-
act_ru_execution 运行时流程执行实例表
-
act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
-
act_ru_job 运行时定时任务数据表
-
act_ru_task 运行时任务节点表
-
act_ru_variable 运行时流程变量数据表
identity表详解
用户组与用户之间通过映射表进行关联
单独的用户信息表
Activiti架构
说明
核心实现层,基于 PVM 的思想和接口,定义了一些关键实体包含 ActivityImpl
(该类抽象了节点实现),FlowElementBehavior
实现(该类抽象了节点指令动作),ExecutionImpl
(流程执行实体类)
命令层,Activiti 在编码模式上直接限定整体风格为命令模式。也就是将业务逻辑封装为一个个的 Command
接口实现类。这样新增一个业务功能时只需要新增一个 Command
实现即可。这里需要特别提到的是,命令本身需要运行在命令上下文中,也就是 CommandContext
类对象。
命令拦截层,采用责任链模式,通过责任链模式的拦截器层,为命令的执行创造条件。诸如开启事务,创建 CommandContext
上下文,记录日志等
业务接口层,面向业务,提供了各种接口。这部分的接口就不再面向框架开发者了,而是面向框架的使用者。
部署层,严格来说,这个与上面说到的并不是一个完整的分层体系。但是为了突出重要性,单独拿出来说。流程运转的前提是流程定义。而流程定义解析就是一切的开始。从领域语言解析为 Java 的 POJO 对象依靠的就是部署层。后文还会细说这个环节。
流程引擎,所有接口的总入口。上面提到的业务接口层,部署层都可以从流程引擎类中得到。因此这里的流程引擎接口其实类似门面模式,只作为提供入口。
ProcessEngine和XXService的关系
EngineService引擎服务
流程引擎是整个activiti
的核心,所有的service
都需要通过流程引擎来获得
Service服务说明
仓库服务
仓库服务是存储相关的服务,一般用来部署流程文件,获取流程文件,查询流程定义信息等操作,是引擎中的一个重要的服务。
RepositoryService repositoryService = engine.getRepositoryService();
1.创建一个模型(模型是用于设计流程图的原型)
Model newModel();
2.保存一个模型
void saveModel(Model);
3.创建部署者
DeploymentBuilder createDeployment();
4.部署
Deployment deploy(DeploymentBuilder);
5.添加:add 为定义的流程授权用户(这个用在什么地方有什么效果暂时未知): addCandidateStarterGroup(processDefinitionId, userId) addCandidateStarterUser(processDefinitionId, userId) 添加模型编辑的资源: addModelEditorSource(modelId, byte[])
addModelEditorSourceExtra(modelId, byte[])
6.查询:create 创建查询,查询部署信息,查询流程定义,查询模型信息:
createModelQuery()
createNativeModelQuery()
createDeploymentQuery()
createNativeDeploymentQuery()
createProcessDefinitionQuery()
createNativeProcessDefinitionQuery()
7.获取资源:get 获取模型,部署和流程定义等资源:
ReadOnlyProcessDefinition getDeployedProcessDefinition(processDefinitionId) List<String> getDeploymentResourceNames(deploymentId)
List<IdentityLink> getIdentityLinksForProcessDefinition(processDefinitionId)
Model getModel(modelId)
…(这里就不具体说明了,使用的时候直接使用提示键)
8.删除资源:delete 删除模型,部署和流程定义的授权群体:
deleteModel(modelId)
deleteDeployment(deploymentId, boolean cascade) cascade决定是否删除流程实例 deleteCandidateStarterUser(processDefinitionId, userId) deleteCandidateStarterGroup(processDefinitionId, groupId)
9.激活和挂起定义的流程:
activate | suspend
定义流程,激活流程和挂起流程都有两种方式:通过流程定义id(这个一般是程序自动生成的)或者是流程定义key(这个是自定义的关键字,用于识别具体是哪个流程。
运行时服务
流程运行时的流程实例,流程定义,流程版本,流程节点等信息,使用运行时服务操作,是引擎中的一个重要的服务。比如请假流程是设计的一个流程,小明请假则是一个具体的流程实例。这项服务可以创建一个流程实例,即启动一个流程,中断或者激活一个流程实例,以及设置信号事件触发器,消息时间触发器(这些和启动流程的条件有关),设置变量,事件监听等一系列和流程实例有关的操作。
RuntimeService runtimeService = engine.getRuntimeService();
service
中的大部分方法都是通过调用commandExecutor.execute()
完成的,
命令模式
命令进行封装,发出命令和执行命令分离
三个部分:CommandExecutor
(命令执行器,用于执行命令),CommandInterceptor
(命令拦截器,用于构建拦截器链),Command
(命令自身,最终业务就是执行该类的 execute
方法)。
路径:org.activiti.engine.impl.interceptor
Command
的接口中只有一个execute
方法,这里才是写命令的具体实现,而CommandExecutor
的实现类在上面已经给出,其包含了一个CommandConfig
和一个命令拦截器CommandInterceptor
,而执行的execute(command)
方法,实际上调用的就是commandInterceptor.execute(commandConfig,command)
。CommandInterceptor
中包含了一个set
和get
方法,用于设置next
(实际上就是下一个CommandInterceptor
)变量。通过这种形式找到拦截器链的下一个拦截器链,将命令传递下去。
过程
Service实现服务的其中一个标准方法是在具体服务中调用commandExecutor.execute(new command())
(这里的command是具体的命令)。其执行步骤就是命令执行器commandExecutor.execute
调用了其内部变量CommandInterceptor first
(第一个命令拦截器)的execute
方法(加上了参数commandConfig
)。CommandInterceptor
类中包含了一个CommandInterceptor
对象next
,用于指向下一个CommandInterceptor
,在拦截器的execute
方法中,只需要完成其对应的相关操作,然后执行一下next.execute(commandConfig,command)
,就可以很简单的将命令传递给下一个命令拦截器,然后在最后一个拦截器中执行command.execute()
,调用这个命令最终要实现的内容就行了。
任务服务
流程运行时的会产生任务,接收、办理、完成等操作使用任务服务完成,是引擎中的一个重要的服务
TaskService taskService = engine.getTaskService();
认证服务
流程运行过程中的一些用户信息,组信息等操作使用认证服务,但是认证服务一般只作为辅助,每一个系统都有一个比较完整的人员系统
//一般不使用自带的认证服务,每个系统都有自己的认证系统
IdentityService identityService = engine.getIdentityService();
历史服务
流程运行时,和运行完成之后的一些历史信息,包括历史任务,历史节点等,是引擎中的一个重要的服务
HistoryService historyService = engine.getHistoryService();
表单服务
流程运行时的任务表单信息,是引擎中的一个辅助的服务,主要用于表单数据的保存和获取,有启动流程的表单和任务过程中产生的表单。
FormService formService = engine.getFormService();
引擎管理服务
提供对流程引擎进行管理和维护服务,查询数据库表的相关信息,Job相关的查询,删除。还有事件日志的相关操作。
ManagementService managementService = engine.getManagementService();
动态Bpmn服务
服务提供对流程定义和部署的存储库的访问,直接操作流程定义,而不需要读取模型,再设计部署
DynamicBpmnService dynamicBpmnService = engine.getDynamicBpmnService();
流程引擎配置
ProcessEngineConfiguration getProcessEngineConfiguration();
加载 activiti.cfg.xml
配置文件
初始化方法
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl类的init()
初始化过程:initCommandExecutors()
前两步都是初始化CommandConfig
,
第一个就是命令执行器的defaultConfig
,主要用在transaction
拦截器。
第三步初始化命令执行者,这也是一个拦截器,不过其放在拦截器的尾端,最后一个执行,它的execute
方法就是调用了command.execute()
。
第四步就是初始化命令拦截器了。
职责链模式
activiti提供了默认的命令拦截器,其顺序是
LogInterceptor -> TransactionInterceptor -> CommandContextInterceptor,
也能看出activiti提供了配置自定义的拦截器可能,customPreCommandInterceptors
和customPostCommandInterceptors
,只需要set进入配置就行了。一个在默认拦截器之前,一个在之后,
#最后一个添加的就是commandInvoker。最终的命令拦截器链就是
customPreCommandInterceptors -> LogInterceptor -> TransactionInterceptor ->
CommandContextInterceptor -> customPostCommandInterceptors -> commandInvoker
默认日志拦截器代码:
默认事务拦截器(使得后续命令运行在事务环境下):
可以使用Spring事务拦截器实现
org.activiti.spring.SpringTransactionInterceptor
默认命令上下文拦截器(有必要的时候创建 CommandContext 对象,并在使用完成后关闭该上下文)
org.activiti.engine.impl.interceptor.CommandContextInterceptor
最后一步初始化命令执行器
包括构建拦截链
流程定义解析
Activiti 遵循 BPMN2.0 规范,通过类org.activiti.bpmn.converter.BpmnXMLConverter
进行 XML 解析,解析为org.activiti.bpmn.model
包下面的与各个 XML 元素定义对应的 POJO 类。
在通过类org.activiti.engine.impl.bpmn.parser.BpmnParser
聚合不同的解析类,将上面步骤解析出来的 POJO 类进一步解析为可以在框架中利用的org.activiti.engine.impl.pvm.process
包下面的类。典型的代表就是 ActivityImpl 类。
命令模式
场景
适合行为进行记录、撤销或重做、事务等处理时。将"行为请求者"与"行为实现者"解耦,将一组行为抽象为对象,可以实现二者之间的松耦合。
调用顺序
调用者→命令→接受者。
Acitivit各个Service从角色上说只是一些协调者或者控制者,他不需要知道具体怎么做,他只是把任务交给了各个Command。
角色
1、received
真正的命令执行对象
2、Command
3、invoker
使用命令对象的入口
对象无需了解业务逻辑对象是否获得了请求, 也无需了解其对请求进行处理的方式。 命令对象会自行处理所有细节工作。
PVM
定义
Activiti 的核心理念就是流程虚拟机(Process Virtual Machine,以下简称 PVM)。
pvm的实现在包org.activiti.engine.impl.pvm
中
包含
ProcessDefinitionImpl
流程定义
ExecutionEntity
管理流程的运行
ActivityImpl
流程节点的定义
AtomicOperation
流程运行方法
ProcessDefinitionImpl是PVM对整个流程定义
通过ProcessDefinitionImpl.createProcessInstance
可以得到流程实例管理接口
ExecutionEntity即对应数据库ACT_RU_EXECUTION表
ExecutionEntity
提供的功能如下:
启动、结束、销毁流程。
对流程元素ActivityImpl
的管理(添加删除修改父节点、实例ID、任务等)。
ExecutionEntity
里几个重要的方法:
initialize()
里面初始化task、job、variable、event
。
start()
是流程启动方法。
performOperation()
是流程执行方法,流程的推动都调用performOperation()
。
ActivityImpl表示单个流程元素
ActivityImpl
表示单个流程元素,比如任务、开始节点、连接线、网关等。它的属性包括:variables、activityBehavior、incomingTransitions、outgoingTransitions
以及元素界面位置等。
说明:
ActivityImpl
是活动节点,在流程图上对应开始节点、结束节点、各种任务节点。
TransitionImpl
是连接线。
ProcessDefinitionImpl
是整个的定义,类图中未画。类ProcessElementImpl
里面有ProcessDefinitionImpl
属性。
AtomicOperation
AtomicOperation
是流程执行的接口,比如流程启动,流程结束,任务启动,任务执行,任务结束等。AtomicOperation
中枚举了所有流程执行方法