一.工作流及其相关概念
1.1 工作流的书面化概念:
工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。
1.2 工作流管理系统的概念:
工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。
1.3 工作流管理联盟(WfMC,Workflow Management Coalition)也给出了关于工作流管理系统的定义:
工作流管理系统是一个软件系统,它通过执行经过计算的流程定义去支持一批专门设定的业务流程。工作流管理系统被用来定义、管理和执行工作流程。
1.4 而工作流管理系统的目标为:
管理工作的流程以确保工作在正确的时间被期望的人员所执行——在自动化进行的业务过程中插入人工的执行和干预。
二.了解Activiti框架提供的23张表
Activiti的后台是有数据库的支持的,所有的表都以ACT_开头。第二部分是表示用途的两个字母标识。用途也和服务的API对应。
- ACT_RE_*:’RE’表示repository。这个前缀的表包含了流程定义和流程静态资源 (图片,规则等等)。
- ACT_RU_*:’RU’表示runtime。这些是运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据。Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。这样运行时表可以一直很小且速度很快。
- ACT_ID_*:’ID’表示identity。这些表包含身份信息,比如用户,组等等。
- ACT_HI_*:’HI’表示history。这些表包含历史数据,比如历史流程实例,变量,任务等等。
- ACT_GE_*:通用数据,用于不同场景下。
2.1 资源库流程规则表
- act_re_deployment:部署信息表
- act_re_model:流程设计模型部署表
- act_re_procdef:流程定义数据表
2.2 运行时数据库表
- act_ru_execution:运行时流程执行实例表
- act_ru_identitylink:运行时流程人员表,主要存储任务节点与参与者的相关信息
- act_ru_task:运行时任务节点表
- act_ru_variable:运行时流程变量数据表
2.3 历史数据库表
- act_hi_actinst:历史节点表
- act_hi_attachment:历史附件表
- act_hi_comment:历史意见表
- act_hi_identitylink:历史流程人员表
- act_hi_detail :历史详情表,提供历史变量的查询
- act_hi_procinst:历史流程实例表
- act_hi_taskinst:历史任务实例表
- act_hi_varinst:历史变量表
2.4 组织机构表
- act_id_group :用户组信息表
- act_id_info:用户扩展信息表
- act_id_membership:用户与用户组对应信息表
- act_id_user:用户信息表
这四张表很常见,基本的组织机构管理,关于用户认证方面建议还是自己开发一套,组件自带的功能太简单,使用中有很多需求难以满足。
2.5 通用数据表
- act_ge_bytearray:二进制数据表
- act_ge_property:属性数据表存储整个流程引擎级别的数据,初始化表结构时会默认插入三条记录
框架的数据表如下图所示
三.实例操作Activiti工作流框架
3.1 配置数据库连接池
activiti.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 连接数据的配置 -->
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti_test?useUnicode=true&characterEncoding=utf8"></property>
<property name="jdbcUsername" value="root"></property>
<property name="jdbcPassword" value="123456"></property>
<!-- 没有表创建表 -->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
3.2 绘制一个请假流程图MyProcess.bpmn
3.3 工作流程的部署,启动,查看个人任务,完成个人任务等小测试
package com.ytdx.test;
import java.util.List;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
/**
* Activiti工作流框架的测试
* @author lhy
*/
public class HelloWorld {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 1.部署流程定义
*/
@Test
public void deploymentProcessDefinition(){
Deployment deployment = processEngine.getRepositoryService() //与流程定义和部署对象相关的Service
.createDeployment() //与流程定义和部署对象相关的Service
.name("第一个工作流测试") //添加部署的名称
.addClasspathResource("MyProcess.bpmn") //从classpath的资源中加载,一次只能加载一个文件
.addClasspathResource("MyProcess.png") //从classpath的资源中加载,一次只能加载一个文件
.deploy(); //完成部署
//控制台输出部署的流程
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
}
/**
* 2.启动流程实例
*/
@Test
public void startProcessInstance(){
String processKey = "HelloWorld"; //流程定义的key
ProcessInstance pi = processEngine.getRuntimeService() //与正在执行的流程实例和执行对象相关的Service
.startProcessInstanceByKey(processKey); //使用流程定义的key启动流程实例,key对应MyProcess.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
System.out.println("流程实例ID:"+pi.getId()); //流程实例ID
System.out.println("流程定义ID:"+pi.getProcessDefinitionId()); //流程定义ID
}
/**
* 3.查询当前人的个人任务
*/
@Test
public void MyPersonalTask(){
String assignee = "海哥";
List<Task> list = processEngine.getTaskService() //与正在执行的任务管理相关的Service
.createTaskQuery() //创建任务查询对象
.taskAssignee(assignee) //指定个人任务查询,指定办理人
.list();
if(list !=null && list.size()>0){
for(Task task : list){
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务的创建时间:"+task.getCreateTime());
System.out.println("任务的办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}else{
System.out.println("暂没有个人任务!");
}
}
/**
* 4.完成我的个人任务
*/
@Test
public void completeMyPersonalTask(){
String taskId = "401"; //任务ID
processEngine.getTaskService() //与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
}
}