浅谈Activiti工作流引擎用户管理

一、前言

近期做了一个简单的财务管理系统,在工作审批模块中运用了工作流引擎。在对比了JBPM与Activiti后,毅然而然决定使用Activiti。本文对Activiti不做过多的介绍,重点在于分析其自身的用户管理模块。刚接触,也只是阐述下自己的个人项目经验。若有不足之处,还望指正。

二、Activiti的用户管理

数据库表:

act_id_user表:

act_id_group表:

act_id_membership表:

从图中可以看出,activiti的用户模块只有用户与组为多对多的关系,仅此而已。

那么现实中呢?我们往往是有分层级关系的。例如小组-->部门-->中心,一层一层的所属关系,这该怎么破?本身我们利用工作流的话,一般都是作为中间件或服务来用。而自己的业务系统已经有一套用户管理模块了,又该如何去整合在一起呢?这些无疑是对于我们干接触的新手来说最为困恼的方面。

接下来我就,以自身所做项目去分析下我是如何处理这些问题的。首先,先介绍下我的项目架构:

1、公司内部有自己的一套管理系统,所有内部系统的用户模块都由其进行管理。

2、工作流引擎将在今后作为一个服务系统,所以运用其REST接口等可以单独独立出来成为一个系统。

3、所以将涉及到业务系统、用户管理系统、工作流引擎三者间的交互。

So……我在此次的项目中摒弃了Activiti的用户管理模块,重新自定义后与Uap系统整合起来。该如何自定义activiti的用户管理模块呢?不急,我会慢慢道来。先给大家介绍篇‘咖啡兔’大神(接触过activiti的伙伴都懂得他是谁)的文章:《同步或者重构Activiti Identify用户数据的多种方案比较》

文章中介绍三种方式:

1、调用IdentifyService接口完成同步。

2、自定义SessionFactory,重写其关于用户与组的增删改查操作。

3、用视图覆盖同名的ACT_ID_系列表。

三种方式各有优劣,而我则用了第二种方式,对其进行重构。

三、如何重构Activiti用户管理模块增删改查

对不同的表的CRUD操作均由一个对应的实体管理器(XxxEntityManager,有接口和实现类),引擎的7个Service接口在需要CRUD实体时会根据接口获取注册的实体管理器实现类(初始化引擎时用Map对象维护两者的映射关系),并且引擎允许我们覆盖内部的实体管理器,查看源码后可以知道有关Identity操作的两个接口分别为:UserIdentityManager和GroupIdentityManager。
查看引擎配置对象ProcessEngineConfigurationImpl类可以找到一个名称为“customSessionFactories”的属性,该属性可以用来自定义SessionFactory(每一个XXxManager类都是一个Session<实现Session接口>,由SessionFactory来管理),为了能替代内部的实体管理器的实现我们可以自定义一个SessionFactory并注册到引擎。
    这种自定义SessionFactory的方式适用于公司内部有独立的身份系统或者公共的身份模块的情况,所有和用户、角色、权限的服务均通过一个统一的接口获取,而业务系统则不保存这些数据,此时引擎的身份模块表就没必要存在(ACT_ID_*)。所以,我重写了其增删改查等方法后,就摒弃了Activiti的用户表,让其与公司的uap管理系统相关联。

1、项目activiti项目使用的是spring mvc框架,所以先看配置:

<!-- Activiti begin -->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
      ………………
     <!-- 自定义用户管理  -->
    <property name="customSessionFactories">
        <list>
            <bean class="me.kafeitu.demo.activiti.service.activiti.custom.CustomUserEntityManagerFactory" />
            <bean class="me.kafeitu.demo.activiti.service.activiti.custom.CustomGroupEntityManagerFactory" />
        </list>
     </property>
    ………………
</beans>

自定义了:CustomUserEntityManagerFactory与CustomGroupEntityManagerFactory两个类,并注入spring管理容器中。

2、自定义类代码:

/**

 * 自定义的Activiti用户会话工厂

 * @author linhy

 *

 */
@Service
public class CustomUserEntityManagerFactory implements SessionFactory {

        @Resource
        private CustomUserManager customUserManager;

        @Override
        public Class<?> getSessionType() {
                // 返回原始的UserManager类型 
                return UserIdentityManager.class;
        }

        @Override
        public Session openSession() {
                // 返回自定义的UserManager实例
                return customUserManager;
        }

}

注意点:(1)实现SessionFactory接口;(2)返回原始类型与返回自定义实例,如上注释代码;

/**

 * 自定义用户管理器

 * @author linhy

 *

 */
@Service("customUserManager")
public class CustomUserManager extends UserEntityManager {

        private Logger logger = LoggerFactory.getLogger(getClass());

        @Override
        public User findUserById(String userId) {
                User user = new UserEntity();
                //引入Uap系统客户端包,关联进行查询
                BaseDto baseDto = RoomyUapUserUtils.getUser(userId);
                if (baseDto.getRemoteStatus() == RemoteStatus.SUCCESS) {
                        UserDto userDto = (UserDto) baseDto;
                        user.setId(userDto.getUserName());
                        user.setFirstName(userDto.getName());
                        user.setLastName(userDto.getName());
                } else {
                        user = null;
                        logger.info("用户名:" + userId + ";无法获取用户信息");
                }
                return user;
        }

        @Override
        public List<Group> findGroupsByUser(String userId) {
               //……
                return list;
        }

        @Override
        public Boolean checkPassword(String userId, String password) {
                //……
                return Boolean.valueOf(true);
        }

        @Override
        public List<User> findUserByQueryCriteria(UserQueryImpl query, Page page) {
                //……
                return list;
        }

        @Override
        public long findUserCountByQueryCriteria(UserQueryImpl query) {
                //……
        }
}

注意点:继承UserEntityManager,进入去看其源码,你就会恍然大悟。

重写自己需要用到的方法,与自己的用户管理系统相关联。组的自定义方式也一样,这里省略。这样,当Activiti要查询用户的时候,就通过uap客户端去查询公司自己的用户管理系统。这就把已有的用户管理模块与Activiti整合在了一起,相对于调用内部接口同步用户数据,我觉得自定义重写过更适合目前的项目需求。

四、结语

本文只介绍了如何实现自定义用户管理,但针对文章一开头所提出的上下级层级关系却未作出解答,将在下一篇文章向大家介绍。本文若有不足之处,敬请指正。

时间: 2025-01-15 05:49:55

浅谈Activiti工作流引擎用户管理的相关文章

Activiti工作流引擎使用

Activiti工作流引擎使用 1.简单介工作流引擎与Activiti 对于工作流引擎的解释请参考百度百科:工作流引擎 1.1 我与工作流引擎 在第一家公司工作的时候主要任务就是开发OA系统,当然基本都是有工作流的支持,不过当时使用的工作流引擎是公司一些牛人开发的(据说是用一个开源的引擎修改的),名称叫CoreFlow:功能相对Activiti来说比较弱,但是能满足日常的使用,当然也有不少的问题所以后来我们只能修改引擎的代码打补丁. 现在是我工作的第二家公司,因为要开发ERP.OA等系统需要使用

浅谈软件项目的需求管理

软件项目区别于其它项目的最显著的特征是其不可见性,它不像硬件购销.建筑工程,都是实实在在可见的东西.而软件项目在系统交付之前很长一段时间,客户是无法感知自己想要的系统究竟是什么样子.因此,需求管理就显得十分重要,据相关统计数据分析,软件项目90%以上失败的原因都在于没有重视需求或者需求管理方面做的不到位导致的. 需求管理作为软件项目管理的一个重要内容,贯穿项目实施的全生命周期.俗话说:万事开头难.需求作为软件开发的第一个环节,其重要性不言而喻.市面上关于需求管理的相关理论和书籍很多,但多数停留在

浅谈C++容器动态内存管理的优化

在信息学竞赛中,C++的容器的用途非常广泛,但经常因常数过大而超时.怎样才能提高它们的效率呢? 我们知道,容器是存储同一类对象的对象,既然"对象"我们无法改变,那么我们只能从"存储"入手,不难想到,不同容器在实现上的根本区别是它们对应着不同的内存组织方式,内存管理无疑是这种实现的核心,所以优化内存管理是加快容器效率的最好途径之一. 一.内存分配器简介 怎样才能优化内存管理呢?很简单,C++为我们提供了这样的接口,我们可以通过自定义容器模板中的最后一个allocato

Activiti工作流引擎参考资料

Activiti工作流引擎使用 传智播客Activiti工作流视频教程(企业开发实例讲解)

浅谈职业经理人的团队管理能力

导语:作为一名职业经理人,在进入一家公司的时候,最开始的任务就是要知道如何管理团队,下面良师益友网职业规划师通过多年的观察,对职业经理人团队 管理浅谈以下几点实践体会,望与诸位同仁共勉. 第一点,希望各位职业经理先融入然后再改造团队.企业文化是一家公司的灵魂,任何一家形成规模的企业都会有自己的文化,职业经理人加入一个新团队 之后,最重要的是认同该公司文化.很多职业经理人,在没有得到充分授权的情况下,就开始进行改革,这样做的结果肯定是"出师未捷身先死",在以失败告 诫.此企业成了短命鬼.

浅谈MySQL存储引擎-InnoDB&amp;MyISAM

存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式是不同的.每一种存储引擎都有它的优势和劣势,本文只讨论最常见的InnoDB和MyISAM两种存储引擎进行讨论.本文中关于数据存储形式和索引的可以查看图解MySQL索引 MySQL逻辑架构图: InnoDB存储引擎 InnoDB是默认的事务型存储引擎,也是最重要,使用最广泛的存储引擎.在没有特殊情况下,一般优先使用InnoDB存储引擎. 1??.数据存储形式

【工作流前进之路】Activiti 权限之用户管理

在每一个系统或框架中,用户是少不了的,在Activiti中,同样也给用户数据提供了一套用于管理的API,用户数据保存在ACT_ID_USER表中. 一.创建用户 在<[工作流前进之路]Activiti权限之用户组-数据查询>中,我曾介绍过,使用newGroup 和saveGroup方法来添加用户组.多个用户放在一块就是一个用户组.所以在创建一个用户的时候,和创建用户组基本上一样,具体代码如下: <span style="font-family:Times New Roman;f

Activiti工作流引擎数据库表结构

版权声明:本文为博主原创文章,未经博主允许不得转载.不经过允许copy,讲追究法律责任,欢迎加入我们的学习提升群466355109,可以相互交流 数据库表的命名 Acitiviti数据库中表的命名都是以ACT_开头的.第二部分是一个两个字符用例表的标识.此用例大体与服务API是匹配的. l  ACT_RE_*:'RE'表示repository.带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等). l  ACT_RU_*:'RU'表示runtime.这是运行时的表存储着流程变量

浅谈Chrome V8引擎中的垃圾回收机制

垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带来的内存泄露问题.但使用了垃圾回收即意味着程序员将无法掌控内存.ECMAScript没有暴露任何垃圾回收器的接口.我们无法强迫其进 行垃圾回收,更无法干预内存管理 内存管理问题 在浏览器中,Chrome V8引擎实例的生命周期不会很长(谁没事一个页面开着几天几个月不关),而且运行在用户的机器上.如果