IdentityService
- 管理用戶
- 管理用戶組
- 用戶與用戶組的關系(MemberShip)
示例
下面是個關于創建用戶,用戶組和二者之間的關系的示例:
// 創建用戶并保存用戶
IdentityService identityService = processEngine.getIdentityService();
User user1 = identityService.newUser("user1");
User user2 = identityService.newUser("user2");
user1.setEmail("user1@126.com");
user2.setEmail("user2@126.com");
identityService.saveUser(user1);
identityService.saveUser(user2);
// 創建用戶組并保存
Group group1 = identityService.newGroup("group1");
identityService.saveGroup(group1);
// 建立用戶和用戶組之間的關系
identityService.createMembership("user1","group1");
identityService.createMembership("user2","group1");
// 查詢用戶組中的用戶
List<User> userList = identityService.createUserQuery()
.memberOfGroup("group1")
.listPage(0,100);
// 查詢用戶對應的用戶組列表
List<Group> 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<String, Entity>()); // 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中的邏輯,如果要擴展其他功能,可以在第二層命令執行器的部分定義自己需要的命令,并使用命令執行器去執行。