Activiti中自定义用户组、重构SessionFactory

项目中使用activiti做的总结,记录一下方便回顾,也希望可以帮到需要帮助的人。

不使用activiti自带的act_id_*表,自定义管理器进行操作。我们项目让独立出来一个微服务,自定义了ActUser(用户)和Role(角色)ManyToMany

自定义用户组的方法有三种:自定义SessionFactory、创建视图、同步数据。

以下示例使用自定义SessionFactory来实现。

查看源文件可知Activiti内部与数据库交互是使用MyBatis实现的,如下图。

在这里插入图片描述

Activiti的每一张表都对应一个EntityManager和EntityManagerFactory,关于identity操作(CRUD)牵扯到两个接口:UserIdentityManager和GroupIdentityManager。
  • EntityManager
    在这里插入图片描述
  • EntityManagerFactory
    在这里插入图片描述
  • UserIdentityManager
    在这里插入图片描述
  • GroupIdentityManager
    在这里插入图片描述
因此我们只需定义xxxUserManager管理器继承UserEntityManager,xxxGroupManager继承GroupEntityManager(内部写CRDU,把自定义的User和Role转换为Activiti中的实体类型),定义CustomGroupManagerFactory和UserManagerFactory实现SessionFactory(注入自定义的管理器),就可以覆盖原有的Act_id_*,完成自定义用户了。具体实现示例如下:

自定义实体类

  • ActUser(用户)
package com.mycompany.myapp.domain;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 * A ActUser.
 */
@Entity
@Table(name = "act_user")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ActUser implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "rev")
    private Integer rev;

    @Column(name = "first")
    private String first;

    @Column(name = "last")
    private String last;

    @Column(name = "email")
    private String email;

    @Column(name = "pwd")
    private String pwd;

    @Column(name = "picture_id")
    private String pictureId;

    @ManyToMany
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JoinTable(name = "act_user_role",
               joinColumns = @JoinColumn(name = "act_user_id", referencedColumnName = "id"),
               inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Set<Role> roles = new HashSet<>();

    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getRev() {
        return rev;
    }

    public ActUser rev(Integer rev) {
        this.rev = rev;
        return this;
    }

    public void setRev(Integer rev) {
        this.rev = rev;
    }

    public String getFirst() {
        return first;
    }

    public ActUser first(String first) {
        this.first = first;
        return this;
    }

    public void setFirst(String first) {
        this.first = first;
    }

    public String getLast() {
        return last;
    }

    public ActUser last(String last) {
        this.last = last;
        return this;
    }

    public void setLast(String last) {
        this.last = last;
    }

    public String getEmail() {
        return email;
    }

    public ActUser email(String email) {
        this.email = email;
        return this;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPwd() {
        return pwd;
    }

    public ActUser pwd(String pwd) {
        this.pwd = pwd;
        return this;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getPictureId() {
        return pictureId;
    }

    public ActUser pictureId(String pictureId) {
        this.pictureId = pictureId;
        return this;
    }

    public void setPictureId(String pictureId) {
        this.pictureId = pictureId;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public ActUser roles(Set<Role> roles) {
        this.roles = roles;
        return this;
    }

    public ActUser addRole(Role role) {
        this.roles.add(role);
        role.getActUsers().add(this);
        return this;
    }

    public ActUser removeRole(Role role) {
        this.roles.remove(role);
        role.getActUsers().remove(this);
        return this;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof ActUser)) {
            return false;
        }
        return id != null && id.equals(((ActUser) o).id);
    }

    @Override
    public int hashCode() {
        return 31;
    }

    @Override
    public String toString() {
        return "ActUser{" +
            "id=" + getId() +
            ", rev=" + getRev() +
            ", first='" + getFirst() + "'" +
            ", last='" + getLast() + "'" +
            ", email='" + getEmail() + "'" +
            ", pwd='" + getPwd() + "'" +
            ", pictureId='" + getPictureId() + "'" +
            "}";
    }
}
  • Role(角色)
package com.mycompany.myapp.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 * A Role.
 */
@Entity
@Table(name = "role")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "rev")
    private Integer rev;

    @Column(name = "name")
    private String name;

    @Column(name = "type")
    private String type;

    @ManyToMany(mappedBy = "roles")
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JsonIgnore
    private Set<ActUser> actusers = new HashSet<ActUser>();

    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getRev() {
        return rev;
    }

    public Role rev(Integer rev) {
        this.rev = rev;
        return this;
    }

    public void setRev(Integer rev) {
        this.rev = rev;
    }

    public String getName() {
        return name;
    }

    public Role name(String name) {
        this.name = name;
        return this;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public Role type(String type) {
        this.type = type;
        return this;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Set<ActUser> getActUsers() {
        return actusers;
    }

    public Role actusers(Set<ActUser> actusers) {
        this.actusers = actusers;
        return this;
    }

    public Role addActUser(ActUser actuser) {
        this.actusers.add(actuser);
        actuser.getRoles().add(this);
        return this;
    }

    public Role removeActUser(ActUser actuser) {
        this.actusers.remove(actuser);
        actuser.getRoles().remove(this);
        return this;
    }

    public void setActUsers(Set<ActUser> actusers) {
        this.actusers = actusers;
    }
    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Role)) {
            return false;
        }
        return id != null && id.equals(((Role) o).id);
    }

    @Override
    public int hashCode() {
        return 31;
    }

    @Override
    public String toString() {
        return "Role{" +
            "id=" + getId() +
            ", rev=" + getRev() +
            ", name='" + getName() + "'" +
            ", type='" + getType() + "'" +
            "}";
    }
}
1.创建 CustomGroupManager 继承 GroupEntityManager
package com.mycompany.myapp.activiti;

/**
 * 自定义的Activiti用户组管理器
 *
 * @author [email protected]
 * @version 1.0
 * @date 2019-10-09 09:24
 */

import com.mycompany.myapp.activiti.util.ActivitiUserUtils;
import com.mycompany.myapp.domain.ActUser;
import com.mycompany.myapp.domain.Role;
import com.mycompany.myapp.repository.ActUserRepository;
import com.mycompany.myapp.repository.RoleRepository;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.GroupQuery;
import org.activiti.engine.impl.GroupQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.persistence.entity.GroupEntityManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@Component
public class CustomGroupManager extends GroupEntityManager {
    private static final Log logger = LogFactory
        .getLog(CustomGroupManager.class);
    @Autowired
    private ActUserRepository actUserRepository;
    @Autowired
    private RoleRepository roleRepository;

    @Override
    public Group createNewGroup(String groupId) {
        return super.createNewGroup(groupId);
    }

    @Override
    public GroupQuery createNewGroupQuery() {
        // TODO Auto-generated method stub
        return super.createNewGroupQuery();
    }

    @Override
    public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) {
        // TODO Auto-generated method stub
        return super.findGroupByQueryCriteria(query, page);
    }

    @Override
    public long findGroupCountByQueryCriteria(GroupQueryImpl query) {
        // TODO Auto-generated method stub
        return super.findGroupCountByQueryCriteria(query);
    }

//    @Override
//    public GroupEntity findGroupById(String groupId) {
//        // TODO Auto-generated method stub
//        return super.findGroupById(groupId);
//    }

    /**
     * 查找角色
     *
     * @param userId
     * @return
     */
    @Override
    public List<Group> findGroupsByUser(String userId) {
        // TODO Auto-generated method stub
        // return super.findGroupsByUser(userId);
        if (userId == null) {
            return null;
        }
        List<Group> groups = new ArrayList<Group>();
        List<Role> roleList = new ArrayList<Role>();
        Optional<ActUser> optionalUser = actUserRepository.findOneWithEagerRelationships(Long.valueOf(userId));
        if (optionalUser.isPresent()) {
            com.mycompany.myapp.domain.ActUser user = optionalUser.get();
            Set<Role> roles = user.getRoles();
            roles.forEach((s) -> {
                Optional<Role> optionalRole = roleRepository.findById(s.getId());
                if (!optionalRole.isPresent()) {
                    return;
                }
                Role role = optionalRole.get();
                roleList.add(role);
            });
            groups = ActivitiUserUtils.toActivitiGroups(roleList);

        }
        return groups;
    }
//    @Override
//    public List<Group> findPotentialStarterUsers(String proceDefId) {
//        return super.findPotentialStarterUsers(proceDefId);
//    }
}
2. CustomUserManager 继承 UserEntityManager
package com.mycompany.myapp.activiti;

import com.mycompany.myapp.activiti.util.ActivitiUserUtils;
import com.mycompany.myapp.domain.Role;
import com.mycompany.myapp.repository.ActUserRepository;
import com.mycompany.myapp.repository.RoleRepository;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.UserQueryImpl;
import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.impl.persistence.entity.UserEntityManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * @author [email protected]
 * @version 1.0
 * @date 2019-10-09 09:44
 */
@Component
public class CustomUserManager extends UserEntityManager {
    private static final Log logger = LogFactory
        .getLog(CustomUserManager.class);
    @Autowired
    private ActUserRepository actUserRepository;
    @Autowired
    private RoleRepository roleRepository;

    /**
     * 查询单个用户
     *
     * @param userId
     * @return
     */
    @Override
    public User findUserById(String userId) {
        //return super.findUserById(userId);
        User userEntity = new UserEntity();
        Optional<com.mycompany.myapp.domain.ActUser> optionalUser = actUserRepository.findById(Long.valueOf(userId));
        if (!optionalUser.isPresent()) {
            return userEntity;
        }
        com.mycompany.myapp.domain.ActUser user = optionalUser.get();
        userEntity = ActivitiUserUtils.toActivitiUser(user);
        return userEntity;
    }

    @Override
    public List<User> findUserByQueryCriteria(UserQueryImpl query, Page page) {
        // TODO Auto-generated method stub
        return super.findUserByQueryCriteria(query, page);
    }

    @Override
    public long findUserCountByQueryCriteria(UserQueryImpl query) {
        // TODO Auto-generated method stub
        return super.findUserCountByQueryCriteria(query);
    }

    /**
     * 查询用户拥有的角色
     *
     * @param userId
     * @return
     */
    @Override
    public List<Group> findGroupsByUser(String userId) {
        // TODO Auto-generated method stub
        //return super.findGroupsByUser(userId);
        if (userId == null) {
            return null;
        }
        List<Group> gs = null;
        List<Role> roleList = new ArrayList<Role>();
        Optional<com.mycompany.myapp.domain.ActUser> optionalUser = actUserRepository.findById(Long.valueOf(userId));
        if (optionalUser.isPresent()) {
            com.mycompany.myapp.domain.ActUser user = optionalUser.get();
            Set<Role> roles = user.getRoles();
            roles.forEach((s) -> {
                Optional<Role> optionalRole = roleRepository.findById(s.getId());
                if (!optionalRole.isPresent()) {
                    return;
                }
                Role role = optionalRole.get();
                roleList.add(role);
            });
            gs = ActivitiUserUtils.toActivitiGroups(roleList);
            return gs;
        }
        return gs;
    }

    @Override
    public IdentityInfoEntity findUserInfoByUserIdAndKey(String userId,
                                                         String key) {
        // TODO Auto-generated method stub
        return super.findUserInfoByUserIdAndKey(userId, key);
    }

    @Override
    public List<String> findUserInfoKeysByUserIdAndType(String userId,
                                                        String type) {
        // TODO Auto-generated method stub
        return super.findUserInfoKeysByUserIdAndType(userId, type);
    }

    @Override
    public Boolean checkPassword(String userId, String password) {
        // TODO Auto-generated method stub
        return super.checkPassword(userId, password);
    }

    @Override
    public List<User> findPotentialStarterUsers(String proceDefId) {
        // TODO Auto-generated method stub
        return super.findPotentialStarterUsers(proceDefId);
    }

}
3. CustomGroupManagerFactory 实现 SessionFactory
package com.mycompany.myapp.activiti;

/**
 * 自定义的Activiti用户组会话工厂
 *
 * @author [email protected]
 * @version 1.0
 * @date 2019-10-09 09:42
 */

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;

import javax.annotation.Resource;

public class CustomGroupManagerFactory implements SessionFactory {
    //private GroupEntityManager groupEntityManager;
    @Resource
    private CustomGroupManager customGroupManager;

    //@Autowired
    public void setCustomGroupEntityManager(CustomGroupManager customGroupEntityManager) {
        this.customGroupManager = customGroupEntityManager;
    }

    public Class<?> getSessionType() {
        // 返回原始的GroupManager类型
        return GroupIdentityManager.class;
    }

    public Session openSession() {
        // 返回自定义的GroupManager实例
        return customGroupManager;
    }
}
4. CustomUserManagerFactory 实现 SessionFactory
package com.mycompany.myapp.activiti;

/**
 * 自定义的Activiti用户会话工厂
 *
 * @author [email protected]
 * @version 1.0
 * @date 2019-10-09 09:50
 */

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.UserIdentityManager;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class CustomUserManagerFactory implements SessionFactory {
    //private UserEntityManager userEntityManager;
    @Resource
    private CustomUserManager customUserManager;

   // @Autowired
    public void setCustomUserEntityManager(CustomUserManager customUserEntityManager) {
        this.customUserManager = customUserEntityManager;
    }

    public Class<?> getSessionType() {
        // activiti原生类型
        return UserIdentityManager.class;
    }

    public Session openSession() {
        // 返回自定义的UserManager实例
        return customUserManager;
    }
}
activitiConfig.xml中配置一下:

在这里插入图片描述

注意:别忘了启动项上面扫描一下activitiConfig.xml

在这里插入图片描述

什么时候调用自定义的管理器?

答:查询待办task信息的时候会用到。
在这里插入图片描述

TaskUtil
package com.mycompany.myapp.activiti.util;

import org.activiti.engine.task.Task;

import java.util.HashMap;
import java.util.Map;

/**
 * Task转换类
 *
 * @author [email protected]
 * @version 1.0
 * @date 2019-10-10 13:46
 */
public class TaskUtil {
    /**
     * 自定义查询返回属性
     *
     * @param task
     * @return
     */
    public static Map<String, Object> taskMap(Task task) {
        Map<String, Object> map = new HashMap<>();
        map.put("startTime", task.getCreateTime());
        map.put("assignee", task.getAssignee());
        map.put("taskName", task.getName());
        map.put("taskId", task.getId());
        map.put("parentTaskId", task.getParentTaskId());
        map.put("processInstanceId", task.getProcessInstanceId());
        map.put("processDefinitionId", task.getProcessDefinitionId());
        map.put("executionId", task.getExecutionId());
        map.put("description", task.getDescription());
        return map;
    }
}

如果指派了处理人,任务就会到指派人那里,如果未定义指派人,定义了候选组,在候选组中的每个人都可以查询到该流程。如下:taskId:75002任务就是候选组在这里插入图片描述

发布了74 篇原创文章 · 获赞 19 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43770545/article/details/102504203