Activiti流程引擎的用户体系与MIS系统的用户体系打通
将Activiti流程引擎的用户体系与MIS系统的用户体系打通,核心在于解决数据同步和权限映射问题。以下是三种主流方案及其实现细节,结合技术要点与场景适用性分析:
🔄 一、同步用户数据方案
- 接口同步方案(推荐)
• 原理:通过Activiti的IdentityService接口,在MIS系统的用户管理操作中触发同步逻辑。
• 实现步骤:
• 用户新增/更新:
在MIS保存用户时,调用identityService.saveUser()同步至Activiti的ACT_ID_USER表,并关联角色(用户组)。
// 示例:保存用户并同步角色
public void saveUser(User user, List<Long> roleIds) {// 1. 保存用户到业务系统misUserDao.save(user); // 2. 同步到Activitiorg.activiti.engine.identity.User activitiUser = identityService.newUser(user.getId());activitiUser.setEmail(user.getEmail());identityService.saveUser(activitiUser);// 3. 关联角色(用户组)for (Long roleId : roleIds) {identityService.createMembership(user.getId(), roleId.toString());}
}
• 用户删除:
同时删除业务系统和Activiti中的用户及关联关系,避免脏数据。
• 优点:兼容性强,不破坏Activiti原生逻辑;支持增量同步。
• 缺点:需维护两套存储,需保证事务一致性。
- 视图映射方案
• 原理:通过数据库视图将MIS系统的用户表映射为Activiti所需的ACT_ID_*表结构。
• 实现步骤:
- 删除Activiti原生的身份表(如ACT_ID_USER)。
- 创建同名视图,将MIS用户表的字段映射为Activiti要求的字段(如将数字ID转为字符串):
CREATE VIEW ACT_ID_USER AS
SELECT CAST(user_id AS VARCHAR) AS ID_, user_name AS FIRST_, email AS EMAIL_
FROM mis_user;
- 配置引擎禁用原生身份表:
• 优点:无需代码同步,实时性强。
• 缺点:视图性能可能受限;数据类型需严格匹配。
- 自定义身份管理(深度集成)
• 原理:重写Activiti的UserIdentityManager和GroupIdentityManager接口,直接调用MIS系统的身份服务。
• 实现步骤:
• 实现自定义的CustomUserEntityManager,覆盖查询方法(如findUserById),直接调用MIS的API或数据库。
• 注册自定义管理器到引擎:
<bean id="processEngineConfiguration" class="...SpringProcessEngineConfiguration"><property name="customSessionFactories"><list><bean class="com.example.CustomUserEntityManagerFactory"/></list></property>
</bean>
• 优点:彻底避免数据冗余,适合已有统一身份管理的系统。
• 缺点:开发复杂度高,需全面测试兼容性。
⚙️ 二、流程中的用户集成
- 动态任务分配
• 场景:任务办理人需根据业务数据动态指定(如部门主管)。
• 实现:
• 在流程定义中使用表达式变量:
<userTask id="hrTask" activiti:assignee="${hrManagerId}" />
• 启动流程时传入变量:
variables.put("hrManagerId", "1001"); // 从MIS系统获取ID
runtimeService.startProcessInstanceByKey("leaveProcess", variables);
- 流程发起人自动记录
• 场景:需跟踪流程发起人(如请假申请)。
• 实现:
• 启动前设置认证用户:
identityService.setAuthenticatedUserId("currentUser");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("processKey");
• 流程定义中引用发起人:
<startEvent activiti:initiator="applyUserId" />
<userTask activiti:assignee="${applyUserId}" /> <!-- 后续任务分配给发起人 -->
- 基于角色的任务查询
• 场景:根据MIS角色查询用户待办任务。
• 实现:
• 将MIS角色同步为Activiti的Group(用户组):
Group group = identityService.newGroup("role_admin");
group.setName("管理员");
identityService.saveGroup(group);
• 查询时关联用户组:
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("role_admin").list();
📊 三、方案对比与选型建议
方案 适用场景 关键技术点 风险提示
接口同步 多数中小系统,需灵活控制同步时机 IdentityService增量同步 事务一致性、性能开销
视图映射 实时性要求高,数据库兼容性好 视图字段映射、禁用原生表 视图性能、类型转换
自定义身份管理 已有统一身份平台的大型系统 重写UserEntityManager 开发复杂度、版本升级兼容性
💎 四、实践建议
- 权限一致性:确保Activiti中的“用户组”与MIS角色一一对应,避免权限分裂。
- 性能优化:同步操作异步化(如MQ),避免阻塞主业务逻辑。
- 历史数据兼容:升级时需迁移旧流程实例中的用户ID,防止任务分配失效。