Activiti工作流
1.Activiti与jbpm对比
Activiti5使用Spring进行引擎配置以及各个Bean的管理,综合使用IoC和AOP技术,使用CXF作为Web Services实现的基础,使用MyBatis进行底层数据库ORM的管理,预先提供Bundle化包能较容易的与OSGi进行集成,通过与Mule ESB的集成和对外部服务(Web Service、RESTful等)的接口可以构建全面的SOA应用;jBPM5使用jBoss.org社区的大多数组件,以Drools Flow为核心组件作为流程引擎的核心构成,以Hibernate作为数据持久化ORM实现,采用基于JPA/JTA的可插拔的持久化和事务控制规范,使用Guvnor作为流程管理仓库,能够与Seam、Spring、OSGi等集成。
需要指出的是Activiti5是在jBPM3、jBPM4的基础上发展而来的,是原jBPM的延续,而jBPM5则与之前的jBPM3、jBPM4没有太大关联,且舍弃了备受推崇的PVM(流程虚拟机)思想,转而选择jBoss自身产品Drools Flow作为流程引擎的核心实现,工作流最为重要的“人机交互”任务(类似于审批活动)则由单独的一块“Human Task Service”附加到Drools Flow上实现,任务的查询、处理等行为通过Apache Mina异步通信机制完成。
优劣对比:
从技术组成来看,Activiti最大的优势是采用了PVM(流程虚拟机),支持除了BPMN2.0规范之外的流程格式,与外部服务有良好的集成能力,延续了jBPM3、jBPM4良好的社区支持,服务接口清晰,链式API更为优雅;劣势是持久化层没有遵循JPA规范。
jBPM最大的优势是采用了Apache Mina异步通信技术,采用JPA/JTA持久化方面的标准,以功能齐全的Guvnor作为流程仓库,有RedHat(jBoss.org被红帽收购)的专业化支持;但其劣势也很明显,对自身技术依赖过紧且目前仅支持BPMN2。
2.Activiti简介
①Activiti介绍
Activiti 作为一个遵从 Apache 许可的工作流和业务流程管理开源平台,其核心是基于 Java 的超快速、超稳定的 BPMN 2.0 流程引擎,强调流程服务的可嵌入性和可扩展性
②逻辑结构设计 (Activiti使用到的表都是ACT_开头的。)
ACT_RE_*:
‘RE’表示repository(存储),RepositoryService接口所操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
ACT_RU_*:
‘RU’表示runtime,运行时表-RuntimeService。这是运行时的表存储着流程变量,用 户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间 的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
ACT_ID_*:
‘ID’表示identity (组织机构),IdentityService接口所操作的表。用户记录,流程中使用到的用户和组。这些表包含标识的信息,如用户,用户组,等等。
ACT_HI_*:
‘HI’表示history,历史数据表,HistoryService。就是这些表包含着流程执行的历史相关数据,如结束的流程实例,变量,任务,等等
ACT_GE_*:
全局通用数据及设置(general),各种情况都使用的数据。
3.eclipse上安装插件
在help>Install New Software>add
添加上Activiti BPMN 2.0 designer - http://activiti.org/designer/update/
4.Activiti核心API介绍
①.ProcessEngine (activiti核心的API是ProcessEngine类,其他所有的类都是由他而来)
RepositoryService(部署流程定义): Activiti 中每一个不同版本的业务流程的定义都需要使用一些定义文件,部署文件和支持数据 ( 例如 BPMN2.0 XML 文件,表单定义文件,流程定义图像文件等 ),这些文件都存储在 Activiti 内建的 Repository 中。Repository Service 提供了对 repository 的存取服务。
RuntimeService(执行管理,包括启动,查询,删除流程定义):在 Activiti 中,每当一个流程定义被启动一次之后,都会生成一个相应的流程对象实例。Runtime Service 提供了启动流程、查询流程实例、设置获取流程实例变量等功能。此外它还提供了对流程部署,流程定义和流程实例的存取服务。
TaskService(用于管理流程任务,可以从这个类中获取任务的信息):在 Activiti 中业务流程定义中的每一个执行节点被称为一个 Task,对流程中的数据存取,状态变更等操作均需要在 Task 中完成。Task Service 提供了对用户 Task 和 Form 相关的操作。它提供了运行时任务查询、领取、完成、删除以及变量设置等功能。
IdentityService(组织机构管理):Activiti 中内置了用户以及组管理的功能,必须使用这些用户和组的信息才能获取到相应的 Task。Identity Service 提供了对 Activiti 系统中的用户和组的管理功能。
ManagementService:Management Service 提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Activiti 系统的日常维护。
HistoryService(记录工作流程的历史记录,包含流程变量查询,流程查询,流程执行对象查询): History Service 用于获取正在运行或已经完成的流程实例的信息,与 Runtime Service 中获取的流程信息不同,历史信息包含已经持久化存储的永久信息,并已经被针对查询优化。
FormService(任务表单管理): Activiti 中的流程和状态 Task 均可以关联业务相关的数据。通过使用 Form Service 可以存取启动和完成任务所需的表单数据并且根据需要来渲染表单。
②ProcessDefinition(流程定义对象)
可以从这个类中获取资源文件等等
③ProcessInstance(流程定义的执行实例)
代表流程定义的执行实例,一个流程实例包含这一个流程上面的所有的节点,那么我们可以通过这个类获取到整个流程中当前所有信息,一个流程实例表示一个流程从开始到结束的最大流程分支,即一个流程只有一个流程实例。
④Execution
activiti中用这个对象描述流程执行的每一个节点。在没有并发的情况下,Execution即为ProcessInstance。流程按照流程定义的规则执行一次的过程就可以表示执行对象Execution。
查看源代码即可发现,ProcessInstance集成了Execution。
在单线流程中Execution即为ProcessInstance,但是在并发情况,即有分支流程的情况下,每一条流程就有一个Execution了。
总结:
* 一个流程中,流程执行对象(Execution)可以有多个,但是流程实例对象(ProcessInstance)只能有一个。
* 当流程按照流程定义的规则只执行一次的时候,流程执行对象(Execution)即为流程实例对象(ProcessInstance)。
5.Activiti Demo
1>创建流程引擎对象
ProcessEngine processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource(“activiti.cfg.xml”)
.buildProcessEngine();
2>部署流程定义
RepositoryService repositoryService = processEngine.getRepositoryService();
3>创建流程实例
RuntimeService runtimeService = processEngine.getRuntimeService();
4>部署相关的流程配置
repositoryService.createDeployment()
.addClasspathResource("Interview.bpmn")
.deploy();
5>获取流程实例
String procId = runtimeService.startProcessInstanceByKey("流程ID").getId();
6>获取任务
TaskService taskService = processEngine.getTaskService();
①//获取人力资源部组可能要操作的任务
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list();
for (Task task : tasks) {
//设置张三代办 claim it
taskService.claim(task.getId(), "张三");
}
//审核张三当前的获取的任务数量
tasks = taskService.createTaskQuery().taskAssignee("张三").list();
for (Task task : tasks) {
//张三执行任务
taskService.complete(task.getId());
}
或者
②//获取张三可能要操作的任务
List<Task> tasks taskService.createTaskQuery().taskAssignee("张三").list();
for (Task task : tasks) {
//张三执行任务
taskService.complete(task.getId());
}
7>HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processId).singleResult();
//流程结束时间
historicProcessInstance.getEndTime();