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任務就是候選組在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章