Activiti工做流引擎自己配套了包括User、Group的Identify模块,可是实际上公司内部各个部门关系、领导下级等关系都很复杂,Activiti自身的id模块就显得有些弱了。java
有关自定义Activiti用户群组表的具体方式有三种,本文只详细介绍第二种:spring
方案一:经过数据推送方式同步数据到引擎的身份表,须要把数据备份到引擎的身份表或者公司有平台或者WebService推送用户数据的推荐使用数据库
方案二:自定义SessionFactory,非侵入式替换接口实现,对于公司内部有统一身份访问接口的推荐使用ide
方案三:不须要编写Java代码,只须要建立同名视图便可学习
引擎内部与数据库交互使用的是MyBatis,Activiti的每一张表都有一个对应的XxxEntityManager(实体管理类,有接口和实现类)和XxxEntityManagerFactory(实体管理工厂类)。this
引擎的7个Service接口在须要CRUD实体时会根据接口获取注册的实体管理器实现类(初始化引擎时引擎会使用Map对象维护二者的映射关系),而引擎容许咱们本身注册实体管理器实现类,查看源码后能够知道有关Identity操做的两个接口分别为:UserIdentityManager和GroupIdentityManager。spa
例以下图:code
User和Group同理,这里以User实体管理类举例,其继承的AbstractManager实现了Session。xml
查看引擎配置对象ProcessEngineConfigurationImpl类能够找到一个名称为“customSessionFactories”的属性,该属性能够用来自定义SessionFactory(从上文能够看到每个XxxEntityManager都是一个Session<实现了Session接口>,并由SessionFactory来管理)对象
为了能替代内部的实体管理器实现类,咱们能够自定义一个SessionFactory并注册到引擎。
这种自定义SessionFactory的方式适用于公司内部有独立的身份系统或者公共的身份模块的状况,全部和用户、角色、权限的服务均经过一个统一的接口获取,而业务系统则不保存这些数据,此时引擎不会再使用本来的身份模块表(ACT_ID_*)。
配置文件:
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> ... ... <!-- 自定义用户、用户组的配置 --> <property name="customSessionFactories"> <list> <bean class="xxx.xxx.xxx.xxx.CustomUserEntityManagerFactory"> <property name="customUserEntityManager"> <bean class="xxx.xxx.xxx.xxx.CustomUserEntityManager"> <property name="CustomUserManager"> <bean class="xxx.xxx.xxx.xxx.CustomUserManager"/> </property> </bean> </property> </bean> <bean class="xxx.xxx.xxx.xxx.CustomGroupEntityManagerFactory"> <property name="customGroupEntityManager"> <bean class="xxx.xxx.xxx.xxx.CustomGroupEntityManager"> <property name="customGroupManager"> <bean class="xxx.xxx.xxx.xxx.CustomGroupManager"/> </property> </bean> </property> </bean> </list> </property> </bean>
以自定义User为例
1、须要自定义对应的SessionFactory,这里是你可否成功注册自定义管理类的关键,getSessionType()是返回给引擎XxxEntityManager的接口(前文有说),然后经过openSession()返回给引擎你自定义的CustomXxxEntityManager。
public class CustomUserEntityManagerFactory implements SessionFactory { private CustomUserEntityManager customUserEntityManager; public void setCustomUserEntityManager(CustomUserEntityManager customUserEntityManager) { this.customUserEntityManager = customUserEntityManager; } @Override public Class<?> getSessionType() { // 返回原始的UserManager类型 return UserIdentityManager.class; } @Override public Session openSession() { // 返回自定义的UserManager实例 return customUserEntityManager; } }
2、须要完成自定义的CustomXxxEntityManager类,这里我只覆盖了两种方法,其中CustomUserManager类与引擎无关,你能够在里面注入dao层接口(dao层接口和实现类,与CustomUserManager类分开能够方便往后维护)
public class CustomUserEntityManager extends UserEntityManager { private CustomUserManager customUserManager; public void setCustomUserManager(CustomUserManager customUserManager) { this.customUserManager = customUserManager; } @Override public BpmUser findUserById(String userId) { return customUserManager.findUserById(userId); } @Override public List<Group> findGroupsByUser(String userId) { return customUserManager.findGroupsByUser(userId); } }
3、使用,由于咱们已经成功注册即覆盖了引擎自带的管理类,因此直接使用service中的方法便可
Boolean judge = processEngine.getIdentityService() .checkPassword(bpmUser.getUserId(),bpmUser.getUserPasswd());
此种方法不是为所欲为的。首先,由于是引擎启动后咱们自定义的管理类才被注册进去,而service中的方法是引擎启动前源码就定义好的,因此你只能重写引擎管理类中已有的那几个方法。
其次,重写主要的限制在于返回值,譬如上文我重写了两个方法,我自定义的BpmUser必需要继承引擎自带的User。另外一个方法的返回值List<Group>更麻烦,个人BpmGroup不只仅须要继承Group,更须要在装填List时“偷梁换柱”,以下,若是你直接返回bpmGroupList是必定会报错的!
public List<Group> findGroupsByUser(String userId) { List<BpmGroup> bpmGroupList=customUserDao.findGroupsByUser(userId); List<Group> groupList = new ArrayList<>(); for (BpmGroup bpmGroup:bpmGroupList){ groupList.add(bpmGroup); } return groupList; }
欢迎留言,欢迎联系我,互相学习, QQ:1144901177
但愿转载的时候能够贴上本文地址,感谢!