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();//直接調用底層實現;