Activiti中的流程历史保存流程发起人的方法

        Activiti中流程的历史信息保存在ACT_HI_ACTINST表中,流程历史信息保存在ACT_HI_PROCINST表中,咱们能够经过API或者直接写SQL进行查询,可是这里面并无流程发起人的信息,流程发起人信息有的时候仍是很是必要的,好比查询某人发起的流程或者作相关的统计等。spring

        鉴于ACT_HI_ACTINST中保存了流程的活动历史信息,咱们仍是想在这个表上作文章,可是这个表中并无发起人等相关的字段,这时候,咱们发现,当一个流程刚发起时,ACT_TYPE_为startEvent,这时ASSIGNEE_为空,若是咱们能借用这个字段,保存申请人,查询起来代码仍是比较优雅的,虽然这个字段自己的含义不是申请人。ide

        另外,ACT_HI_PROCINST表中还有一个START_USER_ID_字段,可是默认为空。经过上述两种保存流程发起人的方式,在不一样的场景中都可以经过简单的方式查询到流程的发起人信息。测试

        下一步,就是研究Activiti的代码了,看看能不能找到相应的扩展点,解决这个问题。线程

        通过研究,找到了扩展点,开发起来仍是比较方便的,下面进行详细描述,注意,本文的开发基于Activiti5.15.1版本,大致扫了下代码,更新的5.17版本应该也兼容,但未通过测试。code

        对于流程发起时保存ACT_HI_ACTINST表和ACT_HI_PROCINST表的代码,在DefaultHistoryManager类的recordProcessInstanceStart方法中,因此咱们只要想办法继承这个类,而后覆写这个方法便可,而DefaultHistoryManager的建立,是在DefaultHistoryManagerSessionFactory中,而DefaultHistoryManagerSessionFactory的初始化,是在ProcessEngineConfigurationImpl中的initSessionFactories方法,找到这里,思路已经很是清晰了,须要写的代码没有多少。继承

        另外,还须要注意一点,Activiti中有一个线程局部变量,保存着线程上下文有关的用户信息,为Authentication中的authenticatedUserIdThreadLocal,而且该类提供相关的API进行赋值和取值,所以咱们须要在流程发起以前设置该局部变量。开发

        1、扩展ProcessEngineConfigurationImpl,若是使用Spring集成的话,继承SpringProcessEngineConfiguration类,覆写initSessionFactories方法,在该方法中调用addSessionFactory方法添加新的自定义DefaultHistoryManagerSessionFactory;get

        2、扩展DefaultHistoryManagerSessionFactory,覆写openSession方法,在该方法中建立新的DefaultHistoryManager;it

        3、扩展DefaultHistoryManager,覆写recordProcessInstanceStart方法,在该方法中为assign字段赋值便可,至于当前的流程发起人获取方法,能够调用Authentication的API获取;io

    具体代码以下所示:

import org.activiti.spring.SpringProcessEngineConfiguration;

public class ProcessEngineConfiguration extends SpringProcessEngineConfiguration {

    @Override
    protected void initSessionFactories() {
        super.initSessionFactories();
        super.addSessionFactory(new ProcessHistoryManagerSessionFactory());
    }
}

    

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.persistence.DefaultHistoryManagerSessionFactory;

public class ProcessHistoryManagerSessionFactory extends DefaultHistoryManagerSessionFactory {

    @Override
    public Session openSession() {
        return new ProcessHistoryManager();
    }
}

    

public class ProcessHistoryManager extends DefaultHistoryManager {
    @Override
    public void recordProcessInstanceStart(ExecutionEntity processInstance) {
        if(isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
          HistoricProcessInstanceEntity historicProcessInstance = new HistoricProcessInstanceEntity(processInstance);
          getDbSqlSession().insert(historicProcessInstance);
      
          IdGenerator idGenerator = Context.getProcessEngineConfiguration().getIdGenerator();
          
          String processDefinitionId = processInstance.getProcessDefinitionId();
          String processInstanceId = processInstance.getProcessInstanceId();
          String executionId = processInstance.getId();
      
          HistoricActivityInstanceEntity historicActivityInstance = new HistoricActivityInstanceEntity();
          historicActivityInstance.setId(idGenerator.getNextId());
          historicActivityInstance.setProcessDefinitionId(processDefinitionId);
          historicActivityInstance.setProcessInstanceId(processInstanceId);
          historicActivityInstance.setExecutionId(executionId);
          historicActivityInstance.setActivityId(processInstance.getActivityId());
          historicActivityInstance.setActivityName((String) processInstance.getActivity().getProperty("name"));
          historicActivityInstance.setActivityType((String) processInstance.getActivity().getProperty("type"));
          Date now = Context.getProcessEngineConfiguration().getClock().getCurrentTime();
          historicActivityInstance.setStartTime(now);
          
          if (processInstance.getTenantId() != null) {
              historicActivityInstance.setTenantId(processInstance.getTenantId());
          }
          //经过Authentication.getAuthenticatedUserId()获取当前线程绑定的用户ID。
          historicActivityInstance.setAssignee(Authentication.getAuthenticatedUserId());
          
          getDbSqlSession().insert(historicActivityInstance);
        }      
    }
}

    Activiti在HistoricProcessInstanceEntity的构造器中已经经过Authentication获取了线程绑定用户ID。所以,咱们只须要在调用runtimeService的startProcessInstance的相关方法以前赋值便可,赋值方法有两种:

identityService.setAuthenticatedUserId();//调用官方的开放API;
Authentication.setAuthenticatedUserId();//直接调用底层实现;
相关文章
相关标签/搜索