美文网首页
activiti学习笔记(七)IdentityService

activiti学习笔记(七)IdentityService

作者: 云师兄 | 来源:发表于2018-10-05 22:10 被阅读26次

    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);
    

    注:

    1. 用户和用户组的关系是多对多的关系。
    2. 每次新增或者修改用户信息都记得使用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;
      }
    

    可以看出:

    1. 判断是不是新建的用户的依据是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中的逻辑,如果要扩展其他功能,可以在第二层命令执行器的部分定义自己需要的命令,并使用命令执行器去执行。

    相关文章

      网友评论

          本文标题:activiti学习笔记(七)IdentityService

          本文链接:https://www.haomeiwen.com/subject/geqcaftx.html