一、简介

Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss jBPM的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务

流程图。

activity工作流springboot activity工作流知会任务_bc

二、Activiti数据库支持

Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

  • ACT_RE_*: ‘RE’ 表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
  • ACT_RU_*: ‘RU’ 表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
  • ACT_ID_*: ‘ID’ 表示 identity。 这些表包含身份信息,比如用户,组等等。
  • ACT_HI_*: ‘HI’ 表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
  • ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。
  1. 资源库流程规则表

act_re_deployment

部署信息表

act_re_model

流程设计模型部署表

act_re_procdef

流程定义数据表

  1. 运行时数据库表

act_ru_execution

运行时流程执行实例表

act_ru_identitylink

运行时流程人员表,主要存储任务节点与参与者的相关信息

act_ru_task

运行时任务节点表

act_ru_variable

运行时流程变量数据表

  1. 历史数据库表

act_hi_actinst

历史节点表

act_hi_attachment

历史附件表

act_hi_comment

历史意见表

act_hi_identitylink

历史流程人员表

act_hi_detail

历史详情表,提供历史变量的查询

act_hi_procinst

历史流程实例表

act_hi_taskinst

历史任务实例表

act_hi_varinst

历史变量表

  1. 组织机构表

act_id_group

用户组信息表

act_id_info

用户扩展信息表

act_id_membership

用户与用户组对应信息表

act_id_user

用户信息表

  1. 通用数据表

act_ge_bytearray

二进制数据表

act_ge_property

属性数据表,存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录

以上数据库表都不是一开始就存在的,也不需要用户手动创建,可以通过代码的方式自动生成,一下有三种初始化数据库的方式:

不管是哪种方式,首先都需要导包,添加 Activiti5 的 jar 包,在 activiti-5.13->wars 目录下是一些示例项目,解压 activiti-rest 项目,导入 activiti-rest 目录中 WEB-INF\lib 下所有包。添加到 classpath 中。另外还需要添加数据库连接的 jar 包。

在Activiti中,在创建核心的流程引擎对象时会自动建表。
1. JDBC 方式

private static void fun1() {
		//JDBC 方式
		ProcessEngineConfiguration processEngineConfiguration = 
				ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
		
		//配置连接数据库信息
		processEngineConfiguration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
		processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti_demo?nullCatalogMeansCurrent=true");
		processEngineConfiguration.setJdbcUsername("root");
		processEngineConfiguration.setJdbcPassword("123456");
		//配置建表策略
		processEngineConfiguration.setDatabaseSchemaUpdate("true");
		
		//使用流程引擎配置对象创建 流程引擎对象
		ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
		
		System.out.println(processEngine);
	}

这里有一个 activiti 的坑,如果使用的是 MySQL8 版本数据库的话,需要在连接数据库的 url 中添加 nullCatalogMeansCurrent=true,否则不会自动生成 activiti 的 23 张表。

2. Spring 方式:添加并制定配置文件
创建一个类似spring结构的配置文件,一般命名为 activiti.cfg.xml,用来做流程引擎的相关配置。

<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 name="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
		<!--配置连接数据库信息-->
		<property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti_demo?nullCatalogMeansCurrent=true"></property>
		<property name="jdbcUsername" value="root"></property>
		<property name="JdbcPassword" value="123456"></property>
		<!--配置建表策略-->
		<property name="databaseSchemaUpdate" value="true"></property>
	</bean>
</beans>
private static void fun2() {
	//Spring 方式
	ProcessEngineConfiguration processEngineConfiguration =
		 ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
	ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
	
	System.out.println(processEngine);
}

3. 快速创建方式(开发中常用)
同样需要 Spring 方式的 activiti.cfg.xml 配置文件,但是 Java 代码中可以使用默认的方式生成对象: ProcessEngines.getDefaultProcessEngine()。在该方法中,会默认读取名为 activiti.cfg.xml 的配置文件。

private static void fun3() {
	//快速创建方式,开发中常用
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	System.out.println(processEngine);
}

三、核心 API

1. ProcessEngine(流程引擎):Activiti中最核心的类,其他的类都是由他而来。

  • RepositoryService:processEngine.getRepositoryService();
  • RuntimeService:processEngine.getRuntimeService();
  • TaskService:processEngine.getTaskService();

RepositoryService

管理流程定义

RuntimeService

执行管理,包括启动、推进、删除流程实例等操作

TaskService

任务管理

HistoryService

历史管理(执行完的数据的管理)

IdentityService

组织机构管理

2. RepositoryService:Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。用于操作数据库中表名为 * _ re _ * 的表。

  • DeploymentBuilder:repositoryService.createDeployment();创建部署流程对象。
  1. name(“流程名称”):给部署的流程设置名称;
  2. addClasspathResource("*.bpmn / *.png"):第一种方式添加 bpnm 和 png 文件;
  3. addZipInputStream(zipInputStream):通过 IO 流的方式读取 bpnm 和 png 的 .zip 文件;
  4. deploy():部署流程。
  • 删除流程定义:repositoryService.deleteDeployment(id)/deleteDeployment(id, true);参数 id 为部署流程 id,普通删除时若流程正在执行则不会被删除;设置级连删除时调用另一个重载方法,设置参数为 true 表示开启级连,级连删除时即使流程正在执行也会被删除。
  • DeploymentQuery:repositoryService.createDeploymentQuery();创建部署流程的查询对象。
  1. getId():获取部署流程 id;
  2. getName():获取部署流程名称。
  3. list():获取所有信息,返回 list 集合;
  4. singleResult():获取单个信息,返回相应类型的对象。
  • ProcessDefinitionQuery:repositoryService.createProcessDefinitionQuery();创建流程定义的查询对象。操作一组 ProcessDefinition 对象。
  1. getDeploymentId():获取部署流程 id;
  2. getName():获取业务流程图的 name;
  3. getResourceName():获取资源文件 bpmn 的名称;
  4. getDiagramResourceName():获取资源文件 png 的名称
  5. getId():获取流程定义 id;
  6. getVersion():获取流程定义版本号;
  7. getKey():获取业务流程图的 id;
  8. list():获取所有信息,返回 list 集合;
  9. singleResult():获取单个信息,返回相应类型的对象。

DeploymentBuilder

用来定义流程部署的相关参数

删除流程定义

分为普通删除与级连删除

DeploymentQuery

用来查询流程部署列表(* _ re _ deployment)

ProcessDefinitionQuery

用来查询流程定义列表(* _ re _ procdef)

3. RuntimeService:Activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。

  • ProcessInstance:runtimeService.startProcessInstanceByKey(processDefinitionKey);启动流程并创建一个流程实例对象,processDefinitionKey 为定义业务流程图是设置的 id。
  1. getProcessDefinitionId():获取流程定义 id;
  2. getProcessInstanceId():获取流程实例 id。
  3. getBusinessKey():获取 BusinessKey ,BusinessKey 是存放用户自定义的 key;
  • ProcessInstanceQuery:runtimeService.createProcessInstanceQuery();创建流程实例的查询对象。可以操作一组 ProcessInstance 对象。

ProcessInstance

流程实例对象,在启动流程时会创建唯一的流程实例对象管理当前启动的流程

ProcessInstanceQuery

用来查询流程实例列表(* _ ru _ execution)

4. TaskService:Activiti的任务服务类。可以从这个类中获取任务的信息。

  • TaskQuery:taskService.createTaskQuery();创建任务查询对象,操作任务列表信息。
  • list():获取所有信息,返回 list 集合;
  • singleResult():获取单个信息,返回相应类型的对象。
  • 添加批注信息:taskService.addComment(taskId, processInstanceId, message),参数分别为任务 id,流程实例 id,以及要写入的批注信息。
  • 完成指定任务:taskService.complete(taskId),根据传入任务 id 完成指定任务。

5. HistoryService:Activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。

  • HistoricTaskInstanceQuery:historyService.createHistoricTaskInstanceQuery();创建历史任务的查询对象,用于查询历史任务信息。
  • HistoricProcessInstanceQuery:historyService.createHistoricProcessInstanceQuery();创建历史流程实例的查询对象,用于查询历史流程实例的信息。
  • HistoricVariableInstanceQuery:historyService.createHistoricVariableInstanceQuery();创建历史流程变量的查询对象,用于查询历史变量的信息。

HistoricTaskInstanceQuery

用于查询历史任务信息

HistoricProcessInstanceQuery

用于查询历史流程实例的信息

HistoricVariableInstanceQuery

用于查询历史变量的信息

6. ProcessDefinition:流程定义类。可以从这里获得资源文件等。

  • 通过部署流程 id 获取资源文件:
  1. repositoryService.getDeploymentResourceNames(deploymentId),返回 list 集合,包含 bpmn 和 png 两个资源名称。
  2. 遍历集合获取 png 资源名称;
  3. repositoryService.getResourceAsStream(deploymentId, sourceName),以流的方式读取指定资源,返回 InputStream.
  • 通过任务 id 获取资源文件:
  1. taskService.createTaskQuery().taskId(taskId).singleResult(),根据任务 id 获取到任务对象 task;
  2. task.getProcessDefinitionId(),由任务对象获取到流程定义 id;
  3. repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId),由流程定义 id 获取到流程定义对象;
  4. processDefinition.getDeploymentId(),processDefinition.getDiagramResourceName(),由流程定义对象获取到部署流程 id 和资源名称。
  5. repositoryService.getResourceAsStream(deploymentId, sourceName),以流的方式读取指定资源,返回 InputStream.

四、流程变量

优点:
(1)从一个任务节点到另一个任务节点的时候,想要带参数到另一个节点,就要用到流程变量;
(2)在有多条分支的情况下,可以使用流程节点控制任务节点的流向。

  • 情况一的使用:作为参数传递
  1. 在一个任务节点完成任务之前,设置好需要传递的参数,例如,taskService().setVariable(taskId, “money”, 1000),通过 taskId 给指定任务添加流程变量。
  2. 另外也可以传递 map 集合,map 集合中保存多个需要传递的参数,调用相应的重载方法设置,例如,taskService().complete(taskId, map);
  • 情况二的使用:控制任务节点的流向
  1. 在流程图的连线中设置条件,当满足条件时沿着该路线走;
  2. 在当前节点完成前,设置传递的参数,传递的参数需要与条件一致;
  3. 当前任务完成后,会比较传入的参数满足那一条路线的条件。
  • 待办人处理:
  1. 直接写死在流程中;
  2. 通过表达式设置,在任务推进时使用流程变量设置待办人;
  3. 监听器方式设置:activiti + ssm 的项目中使用监听器方式设置待办人
    (1)自定义一个类实现 TaskListener 接口,重写 notify(DelegateTask delegateTask) 方法;
    (2)获取 Spring 容器:WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
    (3)获取 bean :EmployeeService employeeService = (EmployeeService) context.getBean(“employeeService”);
    (4)获取 request 对象:HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    (5)从 session 中获取当前待办人:Employee employee = (Employee) request.getSession().getAttribute(“employee_session”);
    (6)根据当前待办人查询下一个待办人:Employee manager = employeeService.findManagerByManagerId(employee.getManagerId());
    (7)设置待办人信息:delegateTask.setAssignee(manager.getName());

五、网关

Activiti 中的网关:Gateway

  • Activiti 中的网关分类:
  1. 排他网关:当前节点完成后有多条路线时,自会选择其中一条路线执行下去。
  2. 并行网关:当前节点完成后有多条路线,可以并行执行多条路线,然后再合并。