IdentityService
- 管理用户
- 管理用户组
- 用户与用户组的关系(MemberShip)
示例
下面是个关于创建用户,用户组和二者之间的关系的示例:
// 创建用户并保存用户
IdentityService identityService = processEngine.getIdentityService();
User user1 = identityService.newUser("user1");
User user2 = identityService.newUser("user2");
user1.setEmail("[email protected]");
user2.setEmail("[email protected]");
identityService.saveUser(user1);
identityService.saveUser(user2);
// 创建用户组并保存
Group group1 = identityService.newGroup("group1");
identityService.saveGroup(group1);
// 建立用户和用户组之间的关系
identityService.createMembership("user1","group1");
identityService.createMembership("user2","group1");
// 查询用户组中的用户
List userList = identityService.createUserQuery()
.memberOfGroup("group1")
.listPage(0,100);
// 查询用户对应的用户组列表
List groupList = identityService.createGroupQuery()
.groupMember("user1")
.listPage(0,100);
// 修改用户信息
User user11 = identityService.createUserQuery().userId("user1").singleResult();
user11.setLastName("dd");
identityService.saveUser(user11);
注:
- 用户和用户组的关系是多对多的关系。
-
每次新增或者修改用户信息都记得使用saveUser方法进行保存。关于这个保存用户信息的方法对应的实现逻辑图如下:
由上图可知,activiti使用了命令模式,在第二层通过命令执行器来执行具体的命令,所以主要在于SaveUserCmd命令的实现,看下IdentityServiceImpl实现类源码如下:
public void saveUser(User user) {
commandExecutor.execute(new SaveUserCmd(user));
}
SaveUserCmd类中execute方法的实现如下:
public Void execute(CommandContext commandContext) {
if (user == null) {
throw new ActivitiIllegalArgumentException("user is null");
}
if (commandContext.getUserEntityManager().isNewUser(user)) {
if (user instanceof UserEntity) {
commandContext.getUserEntityManager().insert((UserEntity) user,true);
} else {
commandContext.getDbSqlSession().insert((Entity) user);
}
} else {
commandContext.getUserEntityManager().updateUser(user);
}
return null;
}
上述命令类的execute方法中涉及到UserEntityManager接口的isNewUser,insert,updateUser等各种方法,在具体程序执行的时候调用的是UserEntityManagerImpl实现类,其中涉及方法源码如下:
@Override
public boolean isNewUser(User user) {
return ((UserEntity) user).getRevision() == 0;
}
可以看出:
- 判断是不是新建的用户的依据是User表中版本号字段是否为0。
另外还判断用户对象是否继承于UserEntity类,由于使用identityService.newUser方法实例化用户对象的时候,只给id字断赋值,所以第一次保存的时候user对象没有继承UserEntity类,所以直接执行了下面的分支,DbSqlSession的insert方法实现如下:
public void insert(Entity entity) {
if (entity.getId() == null) {
String id = dbSqlSessionFactory.getIdGenerator().getNextId();
entity.setId(id);
}
Class extends Entity> clazz = entity.getClass();
if (!insertedObjects.containsKey(clazz)) {
insertedObjects.put(clazz, new LinkedHashMap()); // order of insert is important, hence LinkedHashMap
}
insertedObjects.get(clazz).put(entity.getId(), entity);
entityCache.put(entity, false); // False -> entity is inserted, so always changed
entity.setInserted(true);
}
从上述代码可以发现执行insert方法时内部并没有mybatis执行insert方法,只是创建id,并将entity实体放到缓存对象中去。那什么时候才最终持久化到数据库中呢?答案在DbSqlSession的flush方法中:
public void flush() {
determineUpdatedObjects(); // Needs to be done before the removeUnnecessaryOperations, as removeUnnecessaryOperations will remove stuff from the cache
removeUnnecessaryOperations();
if (log.isDebugEnabled()) {
debugFlush();
}
flushInserts();
flushUpdates();
flushDeletes();
}
...
这里面的细节就不再深入了,最终调用mybatis的insert操作,实现数据持久化。
我们再回到之前说的执行图示:
在上图中UserEntityManager类及其下面层次的类都是经过activiti封装好的操作,在实际开发中不需要修改这个如何保存到mybatis中的逻辑,如果要扩展其他功能,可以在第二层命令执行器的部分定义自己需要的命令,并使用命令执行器去执行。