activiti学习笔记(七)IdentityService

2018-10-05  本文已影响26人  云师兄

IdentityService

示例

下面是个关于创建用户,用户组和二者之间的关系的示例:

        // 创建用户并保存用户
        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中的逻辑,如果要扩展其他功能,可以在第二层命令执行器的部分定义自己需要的命令,并使用命令执行器去执行。

上一篇下一篇

猜你喜欢

热点阅读