Activiti原理分析(三)用户管理

简介: Activiti 原理分析系列文章的第三篇。这篇主要研究 Activiti 内置的用户管理系统,以及受理人,候选人等概念。

Activiti 自带一套用户管理系统,维护了用户和用户组的对应关系,通过 identityService 可以对它们进行增删改查。当你在 UserTask 中指定了用户组时,Activiti 就会使用它维护的这个关系寻找用户了。

但是这也为 Activiti 的使用带来了困难,因为一般应用都有一套自建的用户管理,不可能去使用 Activiti 这一套,就不得不花一些成本来对接,而且对接方法都比较 hack,个人觉得这是 Activiti 设计得不太好的地方。

受理人与候选人

一个 UserTask 可以设置一个受理人(Assignee),或者多个候选人。

受理人就是负责完成该任务的人,在审批场景下就可以理解成审批人,只能有一个,如果要有多个的话则应该使用上一篇文章提到的多实例任务。

<!--kermit就是受理人的 id--><userTaskid="theTask"name="my task"activiti:assignee="kermit"/>

候选人可以有一个或者多个,他们都是受理人的“候选”,他们要“抢”任务,谁先调用了 taskService.claim(taskId, userId);,谁就变成了任务的受理人。

<!--两个候选人 kermit与gonzo--><userTaskid="theTask"name="my task"activiti:candidateUsers="kermit,gonzo"/>


<!--management用户组的所有用户作为候选人--><userTaskid="theTask"name="my task"activiti:candidateGroups="management"/>


内置的用户管理

Activiti 中的用户模型非常简单,就是用户和用户组之间的多对多关系,所以只涉及三张表:

  • ACT_ID_USER:用户信息
  • ACT_ID_GROUP:用户组信息
  • ACT_ID_MEMBERSHIP:存储用户和用户组之间的多对多关联


image-20201129122719757.png


流程运行时用户信息

在应用中一般会调用下面的方法查询某个用户的 task:


// 查询所有候选 userId 的任务List<Task>tasks=taskService.createTaskQuery()
                    .taskCandidateUser(userId).list();
// 查询所有 userId 受理的任务List<Task>tasks=taskService.createTaskQuery()
                    .taskAssignee(userId).list();
// 查询所有 userId候选或者受理的任务List<Task>tasks=taskService.createTaskQuery()
                    .taskCandidateOrAssigned(userId).list();


受理人查询

ACT_RU_TASK 表中本来就有一个 ASSIGNEE_ 字段表示受理人,所有当你使用 taskAssignee(userId) 查询时,直接就是用的 ASSIGNEE_=userIdACT_RU_TASK 表中去查的。

候选人查询

在流程运行时还会有一张 ACT_RU_IDENTITYLINK 表,用来记录流程运行时相关的人员信息,比如流程发起人,参与人,Task 的候选人等信息:


image-20201129124614947.png

其中 TYPE_ 有以下几种取值:

  • starter: 流程发起人
  • participant: 流程参与人,当前的受理人就会被记录在这里
  • candidate: Task 对应的候选人或者候选用户组

因为这是一张运行时表,所以里面数据是会随着流程运转不断增删改的。

当你使用 taskCandidateUser(userId) 条件查询时其实就是去这张表里根据 TYPE_='candidate' AND USER_ID_=userId 找到用户候选的 Task

候选用户组

假如你将 UserTask 配置成 activiti:candidateGroups="management" ,如果 userId 属于 manangement 用户组,那么使用 taskCandidateUser(userId) 条件查询,也是能查出该 UserTask 的。

此时就需要用到上一小节提到的用户管理相关表了。Activiti 如果会去 ACT_ID_MEMBERSHIP 中找到该用户的  groupId,然后去 ACT_RU_IDENTITYLINK 中根据 GROUP_ID_ 查。

Activiti 如何与已有用户管理系统对接?

从上面的分析可以看到,Activiti 只有在你配置了 candidateGroups 才可能去查询内置的用户管理信息,所以个人建议是就不要使用 candidateGroups 配置了,全部使用 candidateUsersassignee,然后在 userId 里加入一些特征区分用户组或者别的业务相关的东西,比如加个前缀 GROUP-groupId,之后就全部用自己业务系统里的 id 去查 Task。不用担心这些ID在 Activiti 内置的用户管理系统中没有,Activiti 根本不会去校验这个。

当然也有人研究过一些更加麻烦的对接方法,列出如下,也可以参考:

  • 往 Activiti 内置的用户表中,同步自己业务的用户数据。个人感觉比较麻烦,而且也容易出各种问题
  • 将 Activiti 用户相关存储类用自己的实现类换掉。听起来很复杂,但是因为 Activiti 6 所采用的可插拔的存储层设计,其实只要替换两类就可以了,后面我有空会再研究一下它的存储层设计。而且如果要搞分库分表的话,存储层本来就是要重新弄的,顺手就可以把用户管理换掉。
  • 用业务用户数据的视图替换掉 Activiti 内置用户管理的这三张表。感觉不一定所有的业务用户数据都可以映射到 Activiti 的用户模型,所有通用性有限

参考


相关文章
|
存储 SQL 数据库
SpringSecurity基础-记住我功能实现
Remember me(记住我)记住我,当用户发起登录勾选了记住我,在一定的时间内再次访问该网站会默认登录成功,即使浏览器退出重新打开也是如此,这个功能需要借助浏览器的cookie实现,具体流程如下
98 0
|
存储 SQL 数据库
七.SpringSecurity基础-记住我功能实现
SpringSecurity基础-记住我功能实现
|
XML 数据可视化 Java
activiti框架搭建及问题记录
activiti框架搭建及问题记录
132 0
|
XML 应用服务中间件 数据格式
Activiti入门操作
Activiti入门操作
|
存储 XML 缓存
Activiti原理分析(一)从一个简单流程开始
本系列文章将基于 Activiti 6 源代码对 Activiti 的原理进行深入剖析,让读者快速知其然,同时知其所以然。 第一篇文章将分析一个简单流程在 Activiti 中的执行流程,借此把 Activiti 底层的一些概念快速梳理一遍,让读者对 Activiti 的底层实现有个大概了解,知晓每张表的作用。内容都是笔者从源码里分析出来或者核对过的,比一般的文档更加翔实靠谱。
3716 2
Activiti原理分析(一)从一个简单流程开始
|
Java 数据库 Spring
Activiti 6.x【2】activiti6.0 基本流程讲解与开发前奏
版权声明:转载注明出处就OK的说,有些东西会转载,都会注明的说= =如果有冒犯麻烦见谅 https://blog.csdn.net/Pan1458689676/article/details/82560185 ...
4997 0
|
数据安全/隐私保护
Activiti流程行为类
课程地址:http://www.shareniu.com/list.htm行为类:链接:http://pan.baidu.com/s/1sljSTcD 密码:uw5a目录:第1课:行为类课程概览第2课:什么是行为类以及什么是行为工厂类和他们的作用第3课:活动行为工厂类初始化原理。
1045 0