Activiti6详细教程 一、为什么选择Activiti 二、核心7大接口、28张表  三、创建BPMN业务流程模型 四、Spring Boot与Activiti 6.0整合 五、项目中的用户、角色与Activiti中的用户、用户组整合 六、请假审批流程

转载https://blog.****.net/babylovewei/article/details/85166182

 https://blog.****.net/qq877507054/article/details/60143099

activiti介绍 Activiti是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理,工作流,服务协作等领域的一个开源,灵活的,易扩展的可执行流程语言框架。

  解决方案 优点 缺点 选型结果 选型原因
开源

Activiti

JBPM 

Flowable

开源

免费

开发工作量大

开发难度大

中文支持不好

Activiti

相对JBPM上手容易

原生支持Spring

与 Spring boot 集成较好

Flowable新出的,使用人数少教程资源少

商用

炎黄盈动

普元

慧正

天翎

宏天

开发工作量小

开发难度小

符合中国国情

闭源

价格高

   

二、核心7大接口、28张表

(一)7大接口

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

  • RepositoryService:提供一系列管理流程部署和流程定义的API。
  • RuntimeService:在流程运行时对流程实例进行管理与控制。
  • TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。
  • IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。
  • ManagementService:提供对流程引擎进行管理和维护的服务。
  • HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。
  • FormService:表单服务。

(二)28张表

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

  1. act_ge_ 通用数据表,ge是general的缩写
  2. act_hi_ 历史数据表,hi是history的缩写,对应HistoryService接口
  3. act_id_ 身份数据表,id是identity的缩写,对应IdentityService接口
  4. act_re_ 流程存储表,re是repository的缩写,对应RepositoryService接口,存储流程部署和流程定义等静态数据
  5. act_ru_ 运行时数据表,ru是runtime的缩写,对应RuntimeService接口和TaskService接口,存储流程实例和用户任务等动态数据

表结构操作: 
3.3.1:资源库流程规则表 

  • 1) act_re_deployment 部署信息表 
  • 2) act_re_model 流程设计模型部署表 
  • 3) act_re_procdef 流程定义数据表 

3.3.2:运行时数据库表 

  • 1) act_ru_execution 运行时流程执行实例表 
  • 2) act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息 
  • 3) act_ru_task 运行时任务节点表 
  • 4) act_ru_variable 运行时流程变量数据表 

3.3.3:历史数据库表 

  • 1) act_hi_actinst 历史节点表 
  • 2) act_hi_attachment 历史附件表 
  • 3) act_ih_comment 历史意见表 
  • 4) act_hi_identitylink 历史流程人员表 
  • 5) act_hi_detail 历史详情表,提供历史变量的查询 
  • 6) act_hi_procinst 历史流程实例表 
  • 7) act_hi_taskinst 历史任务实例表 
  • 8) act_hi_varinst 历史变量表 

3.3.4:组织机构表 

  • 1) act_id_group 用户组信息表 
  • 2) act_id_info 用户扩展信息表 
  • 3) act_id_membership 用户与用户组对应信息表 
  • 4) act_id_user 用户信息表 

这四张表很常见,基本的组织机构管理,关于用户认证方面建议还是自己开发一套,组件自带的功能太简单,使用中有很多需求难以满足 
3.3.5:通用数据表 

  • 1) act_ge_bytearray 二进制数据表 
  • 2) act_ge_property 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录, 
  • 3.4:activiti.cfg.xml(activiti的配置文件) 

Activiti核心配置文件,配置流程引擎创建工具的基本参数和数据库连接池参数。 
定义数据库配置参数: 

  • jdbcUrl: 数据库的JDBC URL。 
  • jdbcDriver: 对应不同数据库类型的驱动。 
  • jdbcUsername: 连接数据库的用户名。 
  • jdbcPassword: 连接数据库的密码。 

基于JDBC参数配置的数据库连接 会使用默认的MyBatis连接池。 下面的参数可以用来配置连接池(来自MyBatis参数): 

  • jdbcMaxActiveConnections: 连接池中处于被使用状态的连接的最大值。默认为10。 
  • jdbcMaxIdleConnections: 连接池中处于空闲状态的连接的最大值。 
  • jdbcMaxCheckoutTime: 连接被取出使用的最长时间,超过时间会被强制回收。 默认为20000(20秒)。 
  • jdbcMaxWaitTime: 这是一个底层配置,让连接池可以在长时间无法获得连接时, 打印一条日志,并重新尝试获取一个连接。(避免因为错误配置导致沉默的操作失败)。 默认为20000(20秒)。

 流程部署相关表 

  • act_re_deployement 部署对象表 
  • act_rep_procdef  流程定义表 
  • act_ge_bytearray 资源文件表 
  • act_ge_prperty  主键生成策略表(对于部署对象表的主键ID)

 流程实例相关表

  •  act_ru_execution 正在执行的执行对象表(包含执行对象ID和流程实例ID,如果有多个线程可能流程实例ID不一样)
  •  act_hi_procinst 流程实例历史表
  •  act_hi_actinst 存放历史所有完成的任务

 Task 任务相关表

  •  act_ru_task 代办任务表 (只对应节点是UserTask的)
  •  act_hi_taskinst 代办任务历史表 (只对应节点是UserTask的) 
  •  act_hi_actinst  所有节点活动历史表 (对应流程的所有节点的活动历史,从开始节点一直到结束节点中间的所有节点的活动都会被记录)

流程变量表

  •  act_ru_variable 正在执行的流程变量表
  •  act_hi_variable 流程变量历史表

 三、创建BPMN业务流程模型

1.将Activiti提供的流程设计器应用activiti-app.war部署到Tomcat的webapps目录。
2.创建新的MySql数据库。修改activiti-appWEB-INFclassesMETA-INFactiviti-app目录下的activiti-app.properties配置文件,默认使用H2内存数据库,创建的模型重启后会丢失,改成使用MySql数据库。
3.浏览器访问http://localhost:8080/activiti-app,登录账户:admin:test
4.创建一个请假审批流程图

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

给每个用户任务指派候选组(有权限执行当前任务的角色)

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程


指派候选组

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

排他网关设置条件分支表达式

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程


5.导出流程图为.bpmn20.xml文件

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程


导出xml文件

四、Spring Boot与Activiti 6.0整合

1.在POM文件中添加依赖

<dependency>
 
    <groupId>org.activiti</groupId>
 
    <artifactId>activiti-spring-boot-starter-basic</artifactId>
 
    <version>6.0.0</version>
 
</dependency>

2.将导出的.bpmn20.xml文件拷贝到项目文件夹/resources/processes下

3.application.properties文件添加配置项

spring.activiti.database-schema-update=true

databaseSchemaUpdate配置项可以设置流程引擎启动和关闭时数据库执行的策略。 databaseSchemaUpdate有以下四个值:

  • false:false为默认值,设置为该值后,Activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配时,将在启动时抛出异常。
  • true:设置为该值后,Activiti会对数据库中所有的表进行更新,如果表不存在,则Activiti会自动创建。
  • create-drop:Activiti启动时,会执行数据库表的创建操作,在Activiti关闭时,执行数据库表的删除操作。
  • drop-create:Activiti启动时,执行数据库表的删除操作在Activiti关闭时,会执行数据库表的创建操作。

4.启动应用,会在数据库里创建28张表,表创建好之后停止应用。application.properties文件修改配置项

  1.  #每次应用启动不检查Activiti数据表是否存在及版本号是否匹配,提升应用启动速度 
  2. spring.activiti.database-schema-update=false

5.application.properties文件增加配置项

  1. #保存历史数据级别设置为full最高级别,便于历史数据的追溯 
  2. spring.activiti.history-level=full

对于历史数据,保存到何种粒度,Activiti提供了history-level属性对其进行配置。history-level属性有点像log4j的日志输出级别,该属性有以下四个值:

  • none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
  • activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
  • audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
  • full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。

6.完成以上步骤,就可以在程序中使用自动注入的方式,使用Activiti的7大接口。

@Autowired
 
private RuntimeService runtimeService;
 
 
 
@Autowired
 
private TaskService taskService;
 
 
 
@Autowired
 
private IdentityService identityService;
 
 
 
@Autowired
 
private RepositoryService repositoryService;
 
 
 
@Autowired

private ProcessEngine processEngine;
 
 
 
@Autowired

private HistoryService historyService;
 


5:核心API

5.1:ProcessEngine

说明: 
 
1) 在Activiti中最核心的类,其他的类都是由他而来。 
 
2) 产生方式:
 
 
 
在前面看到了两种创建ProcessEngine(流程引擎)的方式,而这里要简化很多,调用ProcessEngines的getDefaultProceeEngine方法时会自动加载classpath下名为activiti.cfg.xml文件。 
 
3) 可以产生RepositoryService
 
 
 
4) 可以产生RuntimeService
 
 
 
5) 可以产生TaskService
 
 
 
各个Service的作用: 
 
RepositoryService 管理流程定义 
 
RuntimeService 执行管理,包括启动、推进、删除流程实例等操作 
 
TaskService 任务管理 
 
HistoryService 历史管理(执行完的数据的管理) 
 
IdentityService 组织机构管理 
 
FormService 一个可选服务,任务表单管理 
 
ManagerService
 
 
 
5.2:RepositoryService 
 
是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。 
 
1) 产生方式
 
 
 
2) 可以产生DeploymentBuilder,用来定义流程部署的相关参数
 
 
 
3) 删除流程定义
 
 
 
5.3:RuntimeService 
 
是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。 
 
5.4:TaskService 
 
是activiti的任务服务类。可以从这个类中获取任务的信息。 
 
5.5:HistoryService 
 
是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。 
 
5.6:ProcessDefinition 
 
流程定义类。可以从这里获得资源文件等。 
 
5.7:ProcessInstance 
 
代表流程定义的执行实例。如范冰冰请了一天的假,她就必须发出一个流程实例的申请。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。 
 
5.8:Execution 
 
Activiti用这个对象去描述流程执行的每一个节点。在没有并发的情况下,Execution就是同ProcessInstance。流程按照流程定义的规则执行一次的过程,就可以表示执行对象Execution。 

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

  1. RepositoryService:管理流程定义
     
     
     
    RuntimeService:执行管理,包括启动、推进、删除流程实例等操作
     
     
     
    TaskService:任务管理
     
     
     
    HistoryService:历史管理(执行完的数据的管理)
     
     
     
    IdentityService:组织机构管理
     
     
     
    FormService:一个可选服务,任务表单管理
     
     
     
    ManagerService
     
     
     
    5.2:RepositoryService
     
    是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。
     
     
     
    1) 产生方式
     
      
     
    2) 可以产生DeploymentBuilder,用来定义流程部署的相关参数
     
       
     
    3) 删除流程定义
     
      
     
    5.3:RuntimeService
     
    是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。
     
      
     
    5.4:TaskService
     
    是activiti的任务服务类。可以从这个类中获取任务的信息。
     
     
     
    5.5:HistoryService
     
    是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。
     
     
     
    5.6:ProcessDefinition
     
    流程定义类。可以从这里获得资源文件等。
     
     
     
    5.7:ProcessInstance
     
    代表流程定义的执行实例。如范冰冰请了一天的假,她就必须发出一个流程实例的申请。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。
     
     
     
    5.8:Execution
     
    Activiti用这个对象去描述流程执行的每一个节点。在没有并发的情况下,Execution就是同ProcessInstance。流程按照流程定义的规则执行一次的过程,就可以表示执行对象Execution。
     

五、项目中的用户、角色与Activiti中的用户、用户组整合

每个项目都有自己的用户、角色表,Activiti也有自己的用户、用户组表。因此项目中的用户、角色与Activiti中的用户、用户组要做整合。

 
//项目中每创建一个新用户,对应的要创建一个Activiti用户
 
//两者的userId和userName一致
 
User admin=identityService.newUser("1");
 
admin.setLastName("admin");
 
identityService.saveUser(admin);
 
 
 
//项目中每创建一个角色,对应的要创建一个Activiti用户组
 
Group adminGroup=identityService.newGroup("1");
 
adminGroup.setName("admin");
 
identityService.saveGroup(adminGroup);
 
 
 
//用户与用户组关系绑定
 
identityService.createMembership("1","1");

六、请假审批流程

1.请假申请和请假审批数据库表设计
表设计原则:流程数据和业务数据相分离。Activiti相关表只负责流程的跳转、走向等。流程中产生的业务表单数据、审批意见、附件等存储在开发人员定义的业务表中。流程数据和业务数据之间通过processInstanceId(流程实例ID)和业务数据主键相互关联。

为什么不使用Activiti相关表来存储表单数据和附件?

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

activiti参数表

Activiti为了应用的灵活性和通用性采用了纵表的方式存储表单数据。假设一条请假申请表单数据有10个字段,那就需要10条记录存储原本横表只需要一条记录存储的数据。采用纵表的方式会有如下问题:

会有大量的冗余数据并且数据量会急剧的增长
查询语句复杂,查询效率低
尤其不适合做后期的统计报表分析

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程
activiti附件表

Activiti存储附件使用Blob数据格式,文件存储在数据库里,数据库的数据文件会变得超大,不利于数据库备份和迁移。
请假申请表结构

请假申请表

请假审批表结构

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

请假审批表


2.填写请假申请表单,启动流程实例

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

填写请假申请

 
//启动流程实例,字符串"vacation"是BPMN模型文件里process元素的id
 
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacation");
 
//流程实例启动后,流程会跳转到请假申请节点
 
Task vacationApply = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
 
//设置请假申请任务的执行人
 
taskService.setAssignee(vacationApply.getId(), req.getUserId().toString());
 
 
 
//设置流程参数:请假天数和表单ID
 
//流程引擎会根据请假天数days>3判断流程走向
 
//formId是用来将流程数据和表单数据关联起来
 
Map<String, Object> args = new HashMap<>();
 
args.put("days", req.getDays());
 
args.put("formId", formId);
 
 
 
//完成请假申请任务
 
taskService.complete(vacationApply.getId(), args);

3.待审批列表

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

 
//查出当前登录用户所在的用户组
 
List<Group> groups = identityService.createGroupQuery()
 
        .groupMember(String.valueOf(userId)).list();
 
List<String> groupNames = groups.stream()
 
        .map(group -> group.getName()).collect(Collectors.toList());
 
 
 
//查询用户组的待审批请假流程列表
 
List<Task> tasks = taskService.createTaskQuery()
 
        .processDefinitionKey("vacation")
 
        .taskCandidateGroupIn(groupNames)
 
        .listPage(pageNum - 1, pageSize);
 
 
 
//根据流程实例ID查询请假申请表单数据
 
List<String> processInstanceIds = tasks.stream()
 
        .map(task -> task.getProcessInstanceId())
 
        .collect(Collectors.toList());
 
List<VacationApplyBasicPO> vacationApplyList = 
 
        vacationRepository.getVacationApplyList(processInstanceIds);

4.请假审批功能

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

//查询当前审批节点
 
Task vacationAudit = taskService.createTaskQuery()
 
        .taskId(req.getTaskId()).singleResult();
 
 
 
if (req.getAuditResult() == 1) {//审批通过
 
    //设置流程参数:审批ID
 
    Map<String, Object> args = new HashMap<>();
 
    args.put("auditId", auditId);
 
 
 
    //设置审批任务的执行人
 
    taskService.claim(vacationAudit.getId(), req.getUserId().toString());
 
    //完成审批任务
 
    taskService.complete(vacationAudit.getId(), args);
 
} else {
 
    //审批不通过,结束流程
 
    runtimeService.deleteProcessInstance(vacationAudit.getProcessInstanceId(), auditId);
 
}

5.查看流程图功能

Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程

 
//controller层代码
 
@RequestMapping(value = "/image", method = RequestMethod.GET)
 
public void image(HttpServletResponse response,
 
 @RequestParam String processInstanceId) {
 
    try {
 
        InputStream is = vacationService.getDiagram(processInstanceId);
 
        if (is == null)
 
            return;
 
 
 
        response.setContentType("image/png");
 
 
 
        BufferedImage image = ImageIO.read(is);
 
        OutputStream out = response.getOutputStream();
 
        ImageIO.write(image, "png", out);
 
 
 
        is.close();
 
        out.close();
 
    } catch (Exception ex) {
 
        logger.error("查看流程图失败", ex);
 
    }
 
}
 
 
 
//service层代码
 
@Override
 
public InputStream getDiagram(String processInstanceId) {
 
    //获得流程实例
 
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
 
            .processInstanceId(processInstanceId).singleResult();
 
    String processDefinitionId = StringUtils.EMPTY;
 
    if (processInstance == null) {
 
        //查询已经结束的流程实例
 
        HistoricProcessInstance processInstanceHistory =
 
                historyService.createHistoricProcessInstanceQuery()
 
                        .processInstanceId(processInstanceId).singleResult();
 
        if (processInstanceHistory == null)
 
            return null;
 
        else
 
            processDefinitionId = processInstanceHistory.getProcessDefinitionId();
 
    } else {
 
        processDefinitionId = processInstance.getProcessDefinitionId();
 
    }
 
 
 
    //使用宋体
 
    String fontName = "宋体";
 
    //获取BPMN模型对象
 
    BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
 
    //获取流程实例当前的节点,需要高亮显示
 
    List<String> currentActs = Collections.EMPTY_LIST;
 
    if (processInstance != null)
 
        currentActs = runtimeService.getActiveActivityIds(processInstance.getId());
 
 
 
    return processEngine.getProcessEngineConfiguration()
 
            .getProcessDiagramGenerator()
 
            .generateDiagram(model, "png", currentActs, new ArrayList<String>(),
 
                    fontName, fontName, fontName, null, 1.0);
 
}
  1. Activiti6详细教程
一、为什么选择Activiti
二、核心7大接口、28张表
 三、创建BPMN业务流程模型
四、Spring Boot与Activiti 6.0整合
五、项目中的用户、角色与Activiti中的用户、用户组整合
六、请假审批流程